JavaScript创建对象过程及__proto__和prototype区别

js只有函数对象具备类的概念,要创建对象,必须使用函数对象,函数对象内部的[[constructor]]用于构造对象,[[call]]用于调用对象。
1. var obj = new Object()使用内置的Object函数实例化对象。
2. var obj = {}或者var obj = []使用js引擎触发Object和Array的构造过程。
3. function fn() {};var obj = new fn{}使用用户自定义类型实例化对象。

new创建的对象和函数的prototype对象之间存在继承关系

function A(){
    this.a = 'a in A func';
};
A.prototype.b = 'b in A prototype';
var i = new A();

i.b;//'b in A prototype';
i instanceof A;//true;

A.prototype = {};
i.b;//'b in A prototype';
i instanceof A;//false;
i.__proto__;
// {b: "b in A prototype", constructor: ƒ}

从上面代码看出,将Aprototype置为{}空对象后,i instanceof A;返回false,可见继承关系是通过prototype实现的。

由于new创建对象时将构造函数的prototype属性赋值给实例的__proto__属性,因此__proto__属性和prototype指向同一引用,如果将prototype同对象字面量方式赋值为其他对象的话,则切断了__proto__prototype之间的联系,因为prototype和其最初的引用之间没有关系了,这里考虑引用类型的存储即可明白,__proto__依旧指向之前prototype的引用,所以__proto__属性上存在的属性不会消失。

Aprototype置为{}空对象后对A的实例i来说,i的隐式__proto__属性并未改变,即i被实例化后__proto__不受prototype的影响,相当于实例化后,通过父类prototype继承来的属性和方法都会保存在自身的__proto__属性上,与父类没有关系,因此也不能通过实例更改父类原型上的方法。如下:

i.b = 123
//123
i.__proto__.b
//"b in A prototype"

ObjectFunctionNumberString,等的构造器constructor都是Function,实例对象的构造器会从原型链上继承自父类。

Number.constructor === Function;//true
Number.__proto__ === Function.prototype;//true

Function是最顶层的构造器,他具有自举性,

typeof Function.prototype;//"function"
Function.constructor === Function;//true
Function.__proto__ === Function.prototype;//true

所有函数的__proto__属性都指向Function.prototype,Function__proto__也指向Function.prototype,

function A(){}
A.__proto__ === Function.prototype
//true
Function.__proto__ === Function.prototype;//true
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值