JS 对象原型和原型对象
JS构造函数创建对象的缺陷
instance ![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/0f43b087b89a665a9171a96df7330bfd.png)
上面的例子中 console.log(ldh.sing === zxy.sing);为false , 对于相同的方法,存储的地址不同
- 构造函数存在严重的内存浪费,如果想要所有的对象使用同一个函数需要使用到prototype. JS规定,每个函数都有一个prototype属性,指向另一个对象。构造函数的prototype对象比较特殊,我们通常讲的prototype就是指构造函数的prototype我们可以把那些不变的方法,直接定义在prototype对象上 这样所有的对象实例就可以共享这些方法
- prototype 是一个静态成员 可以看到下面例子中的Star.prototype.sing(ldh.username);是undefined sing . 静态中成员的this 没有意义。
instance
<script>
function Star(username, age) {
this.username = username;
this.age = age;
/* this.sing = function () {
console.log(this.username + ' sing');
} */
}
//static member
Star.gender = 'male';
console.log(Star.gender);
//prototype
Star.prototype.sing = function () {
console.log(this.username + ' sing');
}
//instance
var ldh = new Star('liu', 60);
var zxy = new Star('zhang', 60);
console.log(Star.prototype.sing === ldh.sing);
console.log(ldh.sing === zxy.sing);
Star.prototype.sing(ldh.username);
ldh.sing();
</script>
- 结果如下:
为什么在prototype中定义的函数可以在实例中直接调用?
接上面的例子,在prototype中添加的sing ,可以使用ldh.sing调用呢?
我分别打印了ldh 实例和Star构造函数的属性,可以看到实例中的__proto__和prototype 相同
- proto 称为对象原型,指向原型对象 prototype ldh.proto===Star.prototype为True
- 不同的是 对象原型 是实例成员而原型对象是静态成员
- 对象原型(proto)的作用是为对象的查找机制提供了一个方向,但是它本身是一个非标准属性,在实际开发中,不可以使用这个属性
原型对象的constructor
从上面的分析可以知道 所有的对象原型(proto)都是指向prototype的。而prototype中的constructor是构造函数本身(看图)
当我们需要在prototype中添加多个公用方法,而给prototype赋值时 需要重新给constructor 赋值。表明创建对象的构造函数
//覆盖prototype 并重置构造函数
Star.prototype = {
constructor: Star,
sing: function () {
console.log('sing');
},
moive: function () {
console.log('moive');
}
}
var ldh = new Star('liu', 60);
console.log(Star.prototype);
console.log(ldh.__proto__);
原型链
按照上面的实例,我们可以推导出下面的原型链
JS中对象成员的查找是沿着原型链依次向上的,知道object为止
拓展方法
我们可以操作已有类型的prototype 来拓展已有类型的方法
以数组类型为例:
<script>
Array.prototype.sum = function () {
var sum = 0;
for (let i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
}
var arr = [2, 3, 4, 5];
console.log(arr.sum());
</script>
结论
实验和查资料,得出结论
- 所有的JavaScript 对象都有__proto__(对象的原型),指向构造函数的原型对(prototype)
- 所有原型对象都有一个constructor属性,指向其构造函数,所以这里是一个环,构造函数又有一个prototype属性来指向其对象原型。
- 构造函数中都有原型对象(prototype)的静态成员,来共享属性和方法给构造函数的实例。
- 所有的函数都有prototype 这句话值得商榷,built-in类型的函数就没有
为什么内置对象的函数没有prototype?
看StackOverflow 的文章https://stackoverflow.com/questions/14169384/why-do-built-in-functions-not-have-a-prototype-propertybuilt-in 没有prototype