构造函数
JavaScript中,一个函数除了作为普通意义的函数外,还可以被用来定义为构造函数。什么是构造函数?就是可以用来生成一个对象的函数。例如:
function Student(name,age,city,address){ // this指向构造函数生成的对象 this.name = name; this.age = age; this.city = city; this.address = address; }
函数Student就是一个构造函数,函数名的首字母建议大写,以区别于普通函数。通过new 关键字,构造函数可以创建新的对象。
var xiaoming = new Student("xiaoming",18,"shenzhen","nan shan"); var xiaoping = new Student("xiaoping",19,"guangzhou","tian he"); var xiaojia = Student("xiaojia",18,"shantou","long hu");
xiaoming和xiaoqiang是我们通过构造函数创建的两个对象。以此,我们可以看出Student内部的关键字this指向当前的对象。构造函数虽然没有return语句,但是默认情况下,它返回的是this,也就是当前的对象。普通函数如果没有return语句返回undefined。如果不幸忘记写 new 关键字,那么函数返回的也是undefined。上述代码中的xiaojia变量,接收到的值就是undefined。
prototype属性
构造函数通过prototype属性可以获取构造函数的原型。我们可以通过原型,动态地添加原型方法。例如:
Student.prototype.hello = function(){
alert("Hello," + this.name);
}
上述代码所示,我们动态地给Student的原型添加了一个hello方法。
原型继承链
JavaScript也是一种面向对象的语言。区别于Java语言的继承关系,JavaScript对象是通过原型来继承的。父对象、子对象、孙子对象之间的继承关系形成一个链条,我们称它为原型继承链。如下图所示:
xiaoming对象指向它的原型对象,这个原型对象的构造函数是Student,Student称为这个原型对象的构造器(constructor)。
这个原型对象又是继承于另外一个原型对象,它是由Object构造生成的。
xiaoming.__proto__; //xiaoming的原型对象 Student.prototype; //Student作为原型对象的构造函数 xiaoming.__proto__ == Student.prototype; //true xiaoming.__proto__.constructor == Student;//true xiaoming.__proto__.__proto__ == Object.prototype;//true
生成器
生成器也是一种特殊的函数,它提供了一种持续输出数据的能力。举一个斐波拉契生成器的例子如下:
//生成器 function* fib(n){ a = 0; b = 1; for (let i=0;i < n;i++){ yield a; [a,b] = [b,a+b]; } }
上述fib()生成器的定义如下:
- function*指出这是一个生成器的定义;
- fib是生成器的名称;
- (n)括号内列出生成器的参数,多个参数以逗号分隔;
- { ... }之间的代码是函数体,可以包含若干语句。函数体内部的yield语句是生成器的核心,它表达 了这个生成器对外一个持续数据的输出。
调用生成器
类似于函数的调用一样,我们用生成器的名称,后面紧跟括号和参数列表,对生成器进行调用。经过调用后的生成器才具有对外输出数据的能力。
var g = fib(10);
通过next()函数,不断抽取它的输出
var g = fib(10); g.next(); //{value:0,done:false} g.next(); //{value:1,done:false}
上述代码可知,next()函数返回一个对象。其中一个属性是value,表示返回值;另一个是done,表示抽取是否完成
生成器的遍历
通过一次次调用next()获取生成器的值始终不太方便,我们可以通过for循环对生成器进行遍历。
var g = fib(10); // 遍历生成器 for (;;){ let next = g.next(); if (next.done){ break; } console.log(next.value); }
更方便的遍历方式是通过for...of...的迭代器
var g = fib(10); for (let x of g){ console.log(x); }
文章同时发表在:码农编程网 欢迎访问
本节重点:
- 什么是构造函数,构造函数的特点;
- 什么是原型链;
- 生成器的定义和作用;
- 如何调用生成器;
- 生成器的遍历。