ES6 原型和原型链
1、构造函数和原型 prototype
(1)原型prototype:每个构造函数都有一个prototype属性,指向一个对象。prototype的本质也是一个JavaScript对象,称为原型对象,这个对象的所有属性和方法都会被构造函数所拥有。因此,可将共用的一些方法直接定义在prototype上,这样所有对象实例就可以共享这些方法;
(2)作用:原型prototype的作用是共享方法、节约内存;
// 1、构造函数
function Star(uname, age) {
this.uname = uname;
this.age = age;
}
// 通过原型 prototype 添加共有的方法
Star.prototype.sing = function () {
console.log("I can sing songs");
}
// 所有对象实例都可以使用 prototype 里面的共享方法
var zhangsan = new Star("zhangsan", 18);
var lisi = new Star("lisi", 20);
zhangsan.sing(); //输出 I can sing songs
lisi.sing(); //输出 I can sing songs
2、对象原型 __ proto __
对象自身的一种属性,它指向原型对象prototype,创建的对象实例里面有__ proto __,它指向构造函数的prototype,因此可以使用prototype里面的方法。
3、constructor属性
原型对象prototype和对象原型 __ proto __里面都有一个constructor属性,constructor可以指回构造函数本身。
4、原型链
原型链通俗易懂的理解就是可以把它想象成一个链条,互相连接构成一整串链子!
而原型链中就是实例对象和原型对象之间的链接。每个函数都有一个prototype属性,这个prototype属性就是我们的原型对象,我们拿这个函数通过new构造函数创建出来的实例对象,这个实例对象自己会有一个指针(proto)指向他的构造函数的原型对象!这样构造函数和实例对象之间就通过( proto )连接在一起形成了一条链子。
为什么要使用原型链呢?
1.为了实现继承,简化代码,实现代码重用!
2.只要是这个链条上的内容,都可以被访问和使用到!
原型链的特点
1、就近原则,当我们要使用一个值时,程序会优先查找离自己最近的,也就是本身有没有,如果自己没有,他就会沿着原型链向上查找,如果还没有找到,它还会沿着原型链继续向上查找,找到到达Object
2、引用类型,当我们使用或者修改原型链上的值时,其实使用的是同一个值!
3、JS中每个函数都存在原型对象属性prototype。并且所有函数的默认原型都是Object的实例。
4、每个继承父函数的实例对象都包含一个内部属性proto。该属性包含一个指针,指向父函数的prototype。若父函数的原型对象的proto属性为再上一层函数。在此过程中就形成了原型链。
5、成员查找机制
根据原型链一层与层往上找:
实例对象→→→构造函数原型对象→→→Object原型对象
6、利用prototype对内置对象进行扩展自定义方法
如数组里面有很多方法,但是没有求和方法,我们可以利用原型对象prototype对数组进行扩展:
console.log(Array.prototype); //可以查看数组原有的方法
Array.prototype.sum = function () {
let sum = 0;
for (let i = 0; i < this.length; i++) {
sum += this[i]; // this指向调用这个方法的数组
}
return sum;
}
console.log(Array.prototype); //再次查看数组的方法 可以找到有新扩展的 sum 方法
var arr = [1, 2, 3, 4]
console.log(arr.sum()); //输出 10