本篇博客由标题分为三个方面,让我慢慢分析来,不足之处请指出。
一、关于for的几个函数
1) for in
句法:
for (variable in object) { ... }
variable:每次迭代都会为变量分配不同的属性名称; object:迭代非符号可枚举属性的对象。
描述:一个for...in
仅环比枚举,非符号属性迭代。对象从内置构造等生成Array
和Object
继承来自非枚举的属性Object.prototype
和String.prototype
诸如String
的indexOf()
方法或Object
的toString()
方法。循环将迭代对象本身的所有可枚举属性,以及对象从其构造函数的原型继承的属性(更接近原型链中对象的属性覆盖原型的属性)。
注意:for...in
不应该用于迭代Array
索引顺序很重要的位置。
原因:
数组索引只是具有整数名称的可枚举属性,并且与一般对象属性相同。无法保证for...in
以任何特定顺序返回索引。该for...in
循环语句将返回所有枚举的属性,包括那些非整数的名字和那些继承。
因为迭代的顺序是依赖于实现的,所以迭代数组可能不会以一致的顺序访问元素。因此,在迭代访问顺序很重要的数组时,最好使用for
带有数字索引(或循环)Array.prototype.forEach()
的for...of
循环。
demo:
var str1 = ""; var obj1 = {a: 1, b: 2, c: 3}; for (var pro1 in obj1) { str1 += obj1[pro1]; } console.log(str1); // expected output: "123"
2)for of
for...of在可迭代对象上创建循环迭代,包括:内置String、Array、Array-like对象(例如,参数或NodeList)、TypedArray、Map、Set和用户定义的迭代。它调用一个定制的迭代钩子,其中包含将对象的每个不同属性的值执行的语句。
语法:
for (variable of iterable) { statement }
variable:在每次迭代时,将不同属性的值分配给变量。 iterable:迭代其可迭代属性的对象。
demo:
function* foo(){ yield 1; yield 2; } for (let o of foo()) { console.log(o); // expected output: 1 break; // closes iterator, triggers return }
注意:
如果不在块内重新分配变量,则可以使用const
而不是let
。
demo:
let iterable = [10, 20, 30]; for (const value of iterable) { console.log(value); } // 10 // 20 // 30
在此简单补充下:let:声明块级变量,即局部变量;const:用于声明常量,也具有块级作用域 ,也可声明块级。
3)forEach
注意下这里的forEach是封装好的函数,是一种方法,但其原生也是for循环。
var
arr = [1,2,3];
arr.forEach(alert);
var
arr = [1, 2, 3];
for
(
var
k = 0, length = arr.length; k < length; k++) {
alert(array[k]);
}
forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
forEach方法中的function回调有三个参数:第一个参数是遍历的数组内容,第二个参数是对应的数组索引,第三个参数是数组本身。
简单来说,要用这个方法就是拿来遍历数组。
语法:
arr.forEach(function callback(currentValue[, index[, array]]) { //your iterator }[, thisArg]);
注意: forEach() 对于空数组是不会执行回调函数的。
二、关于构造器或结构体与对象的关系
要说构造体与对象的关系,首先得明白它们的概念。
构造器即构造函数,用于创建对象的函数。它有这些特点:
1、构造函数的首字母必须大写,用来区分于普通函数
2、内部使用的this对象,来指向即将要生成的实例对象
3、使用New来生成实例对象
对象:属性和方法的集合,即变量和函数的封装。每个对象都有一个__proto__属性,指向这个对象的构造函数的原型对象。
原型对象:每个函数都有一个prototype属性,它是一个指向原型对象的指针(原型对象在定义函数时同时被创建)。
而它们之间有怎样的关系呢?
简单来说,定义构造函数,使用new关键字可实例化对象,而每个构造函数都有原型对象prototype,实例化对象也就继承了原型对象。
有一个恰当的比喻,构造函数是妈,原型对象是爸,实例对象是孩子。妈让每个孩子拥有私有能力,爸让它们拥有共有能力(这个共有能力其实都是爸代劳的。
关于构造函数的小demo:
function Person(name, age){//构造器函数 this.name = name; this.age = age; } Person.prototype = {//设置构造器函数prototype指定的对象,即重置原型对象 constructor : Person, sayName : function(){alert(this.name);} } var p1 = new Person("Tom", 29);//实例化对象p1 //{name:"Tom",age:29,__proto__:object},object即原型对象:Person.prototype指向的对象
三、Arrow functions 的介绍
arrow function 也就是箭头函数。
一个箭头函数表达式比一个更短的语法功能表达,没有自己的this
,arguments
,super
,或new.target
。这些函数表达式最适合非方法函数,不能用作构造函数。
基本语法:
(param1, param2, …, paramN) => { statements } (param1, param2, …, paramN) => expression // equivalent to: => { return expression; } // Parentheses are optional when there's only one parameter name: (singleParam) => { statements } singleParam => { statements } // The parameter list for a function with no parameters should be written with a pair of parentheses. () => { statements }
关于箭头函数的一个小demo:
var materials = [ 'Hydrogen', 'Helium', 'Lithium', 'Beryllium' ]; console.log(materials.map(material => material.length)); // expected output: Array [8, 6, 7, 9]
以后应该会对箭头函数进一步学习,文中有错误或不足请指出。