前端资源整理

专业类

HTML

CSS

Javascript

优化

规范

学习类

工具类

Emmet

Git

框架

压缩工具

资源类

网站

资源

自动化构建

Gulp

Sass

杂谈

font-size

汉字,¥10.123456789,font-family:默认


汉字,¥10.123456789,font-family:”Helvetica Neue”


汉字,¥10.123456789,font-family:Helvetica


汉字,¥10.123456789,font-family:STHeiTi


汉字,¥10.123456789,font-family:Arial


汉字,¥10.123456789,font-family:’微软雅黑’

flex test

测试flex-flow在移动端的兼容问题,用手机打开此页面查看效果。尤其最后一个demo:

flex-wrap:nowrap


  • a

  • b

  • c


flex-wrap:wrap



  • a

  • b

  • c


flex-wrap:wrap-reverse



  • a

  • b

  • c


flex-wrap:wrap & flex



  • a

  • b

  • c

Javascript中如何遍历属性

遍历属性,我们首先要搞清楚for in,再来谈遍历:

关于for in

for...in 声明用于对数组或者对象的属性进行循环/迭代操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 对于数组:迭代出来的是数组元素
var mycars = ['Saab','Volvo','BMW'];
for (x in mycars) {
console.log(x); // 0 1 2
console.log(mycars[x]); // Saab Volvo BMW
}

// 对于对象 ,迭代出来的是对象的属性
var obj = {
w: "wen",
j: "jian",
b: "bao"
}
for(var v in obj){
console.log(v); // w j b
console.log(obj[v]); // wen jian bao
}

判断对象是否为 数组/对象 的 元素/属性:

语法为:

1
2
3
for (变量 in 对象) {
在此执行代码
}

当“对象”为数组时,变量指的是数组的下标(索引);

1
2
3
4
5
6
7
var arr = ["a","b","2","3","str"]; 

var result = ("b" in arr);
var result1 = (4 in arr);

console.log(result); //false
console.log(result1); //true

当“对象”为对象时,变量指的是对象的属性;

1
2
3
4
5
6
7
8
9
10
11
var obj = {
w:"wen",
j:"jian",
b:"bao"
};

var result = (2 in obj);
var result1 = ("j" in obj);

console.log(result); //false
console.log(result1); //true

关于for in的其他参考:

关于遍历

JavaScript中,遍历一个对象的属性往往没有在其他语言中遍历一个哈希(有些语言称为字典)的键那么简单,这主要有两个方面的原因:

  • JavaScript中的对象通常都处在某个原型链中,它会从一个或多个的上层原型上继承一些属性;
  • JavaScript中的属性不光有值,它还有一些除了值以外的其他特性,其中一个影响属性遍历的特性就是[[Enumerable]],如果该值为true,则称这个属性是可枚举的,否则反之。

知道了这些,我们就可以把属性的遍历分为四种情况:

注:示例代码中,我们要遍历的对象是浏览器中的window,环境为Chrome43.0.2357.134,代码运行在空白页面中的script标签里.没有Firebug或者其他调试工具的影响(会导入一些全局变量,console等)。

遍历可枚举的自身属性

可枚举的意思就是该属性的[[Enumerable]](可枚举性)特性为true,自身属性的意思就是该属性不是从原型链上继承下来的。

1
2
3
4
5
6
(function () {
var propertys = Object.keys(window); //获得对象上所有可枚举的“实例属性”
console.log(propertys.length); //chrome为7 ["top", "location", "document", "window", "external", "chrome", "propertys"]
console.log(window);
console.log(propertys); //window,document,InstallTrigger,除了最后一个是火狐私有的属性,原来window对象只有两个可枚举的自身属性.window属性指向window对象自身,一般没什么用.
})();

遍历所有的自身属性

特性为不可枚举的属性也并不是遍历不到,ES5给我们提供了getOwnPropertyNames方法,可以获取到一个对象的所有自身属性.

1
2
3
4
5
(function () {
var propertys = Object.getOwnPropertyNames(window); //获得对象上所有的“实例属性”
console.log(propertys.length); //chrome为571
console.log(propertys.join("\n")); //Object,Function,eval等等
})();

遍历可枚举的自身属性和继承属性

继承属性怎么遍历,你应该知道,就是最常用的for in遍历

1
2
3
4
5
6
7
8
9
10
11
12
(function () {
var getEnumPropertyNames = function (obj) {
var props = [];
for (prop in obj) {
props.push(prop);
}
return props;
}
var propertys = getEnumPropertyNames(window);
console.log(propertys.length); // chrome为186
console.log(propertys.join("\n")); // addEventListener,onload等等
})();

遍历所有的自身属性和继承属性

这种遍历主要用在各种js调试工具的代码补全功能上.比如Firebug的.

1
2
3
4
5
6
7
8
9
10
11
12
(function () {
var getAllPropertyNames = function (obj) {
var props = [];
do {
props = props.concat(Object.getOwnPropertyNames(obj));
} while (obj = Object.getPrototypeOf(obj));
return props;
}
var propertys = getAllPropertyNames(window);
console.log(propertys.length); // chrome为719
console.log(propertys.join("\n")); // toString等
})();

Array方法: indexOf、filter、forEach、map、reduce详解

ECMAScript5标准新增了几个数组操作的方法,让我们来看看都是什么:

  • Array.prototype.indexOf
  • Array.prototype.lastIndexOf
  • Array.prototype.every
  • Array.prototype.some
  • Array.prototype.forEach
  • Array.prototype.map
  • Array.prototype.filter
  • Array.prototype.reduce
  • Array.prototype.reduceRight

只介绍其中5个方法:indexOffiltermapforEachreduce,其余请参考:http://kangax.github.io/compat-table/es5/

indexOf

indexOf()方法返回在该数组中第一个找到的元素位置,如果它不存在则返回-1。

没有实现这个方法时,我们这么玩:

1
2
3
4
5
6
7
8
9
10
function getIndexOf(arr, src){
for (var i = 0; i < arr.length; i++) {
if(arr[i] == src){
return i;
}
};
return -1;
}
var arr = ['a','b','c','d'];
console.log(getIndexOf(arr, 'b'));

现在可以这么玩:

1
2
var arr = ['a','b','c','d'];
console.log(arr.indexOf('b'));

一般在写老版本的兼容时,我们会这么玩:

1
2
3
4
5
6
7
8
9
10
11
12
13
Array.prototype.indexOf = function(n){
for (var i = 0; i < this.length; i++) {
if(this[i] == n){
return i;
}
};
return -1;
}

var arr = ['a','b','c','d'];
for(var x in arr){
document.write(arr[x] + '<br>');
}

上面代码本身没有问题,但在IE8以下(含IE8)的浏览器上结果是这样的:

1
2
3
4
5
//a
//b
//c
//d
//function(n){ for (var i = 0; i < this.length; i++) { if(this[i] == n){ return i + '-indexOf'; } }; return -1; }

为什么会这样?得先知道一个原理:预定义的属性不是可枚举的,而用户定义的属性总是可枚举的

IE8以上的浏览器中,indexOf会被认为是预定义属性,使用for in时自然不会被枚举到。而ie8以下的js版本中并没有预定义indexOf,是我们自定义的方法,所以就被枚举到了。

关于for in:可用来遍历一个对象中的所有属性名,该枚举过程将会列出所有的属性,包括函数和你可能不关心的原型中的属性。

所以上面的例子想得到正确的结果,需做如下修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Array.prototype.indexOf = function(n){
for (var i = 0; i < this.length; i++) {
if(this[i] == n){
return i;
}
};
return -1;
}

var arr = ['a','b','c','d'];
for(var x in arr){
if (arr.hasOwnProperty(x)) {
document.write(arr[x] + '<br>');
}
}
  • hasOwnProperty:是用来判断一个对象是否有你给出名称的属性或对象。不过需要注意的是,此方法无法检查该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。
  • isPrototypeOf:是用来判断要检查其原型链的对象是否存在于指定对象实例中,是则返回true,否则返回false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//一个demo解释hasOwnProperty和isPrototypeOf
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function(){
console.log('hello, my name is ' + this.age);
}
Person.prototype.sayFrom = function(from){
this.from = from;
console.log('hi, i come from ' + this.from);
}

var s1 = new Person('xiaomin', '24');
var s2 = new Person('xiaohua', '28');

s1.grade = '30';

console.log(s1.hasOwnProperty('name')); //true
console.log(s1.hasOwnProperty('grade')); //true
console.log(s1.hasOwnProperty('sayHello')); //false
console.log(s1.hasOwnProperty('from')); //false
console.log(Person.prototype.hasOwnProperty("sayHello"));//true
console.log(Person.prototype.hasOwnProperty("from"));//false
console.log(Person.prototype.isPrototypeOf(s1))//true
console.log(Person.prototype.isPrototypeOf(s2))//true

关于枚举,可参考:

filter

filter()方法创建一个新的匹配过滤条件的数组。

没有实现这个方法时,我们这么玩:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var arr = [
{"name":"apple", "count": 2},
{"name":"orange", "count": 5},
{"name":"pear", "count": 3},
{"name":"orange", "count": 16},
];

var newArr = [];

for(var i= 0, l = arr.length; i< l; i++){
if(arr[i].name === "orange" ){
newArr.push(arr[i]);
}
}

console.log("Filter results:",newArr);

现在可以这么玩:

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [
{"name":"apple", "count": 2},
{"name":"orange", "count": 5},
{"name":"pear", "count": 3},
{"name":"orange", "count": 16},
];

var newArr = arr.filter(function(item){
return item.name === "orange";
});


console.log("Filter results:",newArr);

forEach

forEach()为每个元素执行对应的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [1,2,3,4,5,6,7,8];

// Uses the usual "for" loop to iterate
for(var i= 0, l = arr.length; i< l; i++){
console.log(arr[i]);
}

console.log("========================");

//Uses forEach to iterate
arr.forEach(function(item,index){
console.log(item);
});

map

map()对数组的每个元素进行一定操作(映射)后,会返回一个新的数组,

以前这么玩:

1
2
3
4
5
6
7
8
9
10
11
12
13
var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}];

function getNewArr(){
var newArr = [];
for(var i= 0, l = oldArr.length; i< l; i++){
var item = oldArr[i];
item.full_name = [item.first_name,item.last_name].join(" ");
newArr[i] = item;
}
return newArr;
}

console.log(getNewArr());

现在这么玩:

1
2
3
4
5
6
7
8
9
10
var oldArr = [{first_name:"Colin",last_name:"Toh"},{first_name:"Addy",last_name:"Osmani"},{first_name:"Yehuda",last_name:"Katz"}];

function getNewArr(){
return oldArr.map(function(item,index){
item.full_name = [item.first_name,item.last_name].join(" ");
return item;
});
}

console.log(getNewArr());

map()是处理服务器返回数据时是一个非常实用的函数。

reduce

reduce()可以实现一个累加器的功能,将数组的每个值(从左到右)将其降低到一个值。

场景: 统计一个数组中有多少个不重复的单词

befroe:

1
2
3
4
5
6
7
8
9
10
11
12
var arr = ["apple","orange","apple","orange","pear","orange"];

function getWordCnt(){
var obj = {};
for(var i= 0, l = arr.length; i< l; i++){
var item = arr[i];
obj[item] = (obj[item] +1 ) || 1;
}
return obj;
}

console.log(getWordCnt());

now:

1
2
3
4
5
6
7
8
9
10
var arr = ["apple","orange","apple","orange","pear","orange"];

function getWordCnt(){
return arr.reduce(function(prev,next){
prev[next] = (prev[next] + 1) || 1;
return prev;
},{});
}

console.log(getWordCnt());

reduce(callback, initialValue)会传入两个变量。回调函数callback和初始值initialValue。假设函数它有个传入参数,prevnext,indexarrayprevnext你是必须要了解的。

一般来讲prev是从数组中第一个元素开始的,next是第二个元素。但是当你传入初始值initialValue后,第一个prev将是initivalValuenext将是数组中的第一个元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//二者的区别,在console中运行一下即可知晓
var arr = ["apple","orange"];

function noPassValue(){
return arr.reduce(function(prev,next){
console.log("prev:",prev);
console.log("next:",next);

return prev + " " +next;
});
}

function passValue(){
return arr.reduce(function(prev,next){
console.log("prev:",prev);
console.log("next:",next);

prev[next] = 1;
return prev;
},{});
}

console.log("No Additional parameter:",noPassValue());
console.log("----------------");
console.log("With {} as an additional parameter:",passValue());

图解Javascript上下文与作用域

本文尝试阐述Js中的上下文与作用域背后的机制,主要涉及到执行上下文(execution context)、作用域链(scope chain)、闭包(closure)、this等概念。

Execution context

执行上下文(简称上下文)决定了Js执行过程中可以获取哪些变量、函数、数据,一段程序可能被分割成许多不同的上下文,每一个上下文都会绑定一个变量对象(variable object),它就像一个容器,用来存储当前上下文中所有已定义或可获取的变量、函数等。位于最顶端或最外层的上下文称为全局上下文(global context),全局上下文取决于执行环境,如Node中的globalBrowser中的window

阅读全文

图解Javascript原型链

昨天翻微信订阅号,无意间看到这篇关于原型和原型链的文章,觉得其中有很多值得学习的地方,整理如下:

本文尝试阐述Js中原型(prototype)、原型链(prototype chain)等概念及其作用机制。上一篇文章(图解Javascript上下文与作用域)介绍了Js中变量作用域的相关概念,实际上关注的一个核心问题是:“在执行当前这行代码时Js解释器可以获取哪些变量”,而原型与原型链实际上还是关于这一问题。

我们知道,在Js中一切皆为对象(Object),但是Js中并没有类(class);Js是基于原型(prototype-based)来实现的面向对象(OOP)的编程范式的,但并不是所有的对象都拥有prototype这一属性:

阅读全文


Powered by Hexo and Hexo-theme-hiker

Copyright © 2013 - 2019 FE blog All Rights Reserved.

访客数 : | 访问量 :