____proto____、prototype、constructor以及new

____proto____、prototype、constructor的简述

首先,我们必须要清楚,____proto____、constructor是对象特有的,而prototype是函数特有的,因此对象是不存在prototype的,而因为函数也是一个对象,所以函数也有____proto____、constructor。

  1. proto

    它是形成原型链的关键,该属性的作用是,当访问一个属性时,倘若在该对象上没找到对应的属性,则会通过____proto____去查询该对象的父对象(该对象的构造函数的原型prototype),以此类推,而null是原型链的终点,若原型链上都找不到对应的则报错或返回undefine。

  2. prototype

​ 它是函数所特有的原型,意义是使得所有的实例对象共有的公共属性和方法。

  1. constructor

​ 它指向该对象的构造函数,也可用它来分辨变量类型,构造函数中有prototype,prototype也有指向constructor。

通过new来巩固____proto____、prototype、constructor

function F(name){
this.name=name;
}
F.prototype.sayName(){
return "My Name is"+this.name;
}
let f1=new F();
console.log(f1.prototype) //undefine
console.log(f1.__proto__) //{ sayName: [Function (anonymous)] }
console.log(f1.constructor) //[Function: F]
console.log(f1.__proto__===F.prototype) // true
console.log(f1.hasOwnProperty('name')) //true
console.log(f1.hasOwnProperty('constructor')) //false
console.log(F.prototype.hasOwnProperty('constructor')) //true
console.log(F.prototype.constructor.hasOwnProperty('prototype')) //true

如果你能完全知道并理解上诉代码的输出结果,那么你应该掌握了____proto____、prototype、constructor以及new的内涵,接下来我们一起来看看new究竟做了什么,以及f1和F之间的关系,和这些输出结果的原因!

首先,我们来看看new这个关键字它做了什么操作

function Mynew(constructor,...args){
//第一步,创建一个空对象
let obj=Object.create(null);
//第二步 该对象的__proto__指向构造函数的原型prototype,连接原型
obj.__proto__=constructor.prototype
//第三步 执行构造函数,this绑定为obj,对obj进行操作
var result=constructor.apply(obj,args);
//判断构造函数执行是否为对象,若为对象则返回对象,无则返回obj
return typeof result==='object'?result:obj;
}

通过new关键字的操作我们可以发现

  1. 倘若构造函数不返回对象,那么实例对象的____proto____指向构造函数的原型,并且构造函数中倘若出现this.×××=×××,其实是在给实例对象创建新的属性。!!!构造函数中的this不指向prototype!,this指向要看它最终的函数引用,这里构造函数的this指向创建的实例对象obj
  2. 倘若构造函数返回对象,那么实例对象即为新创建的对象!

让我们再来看看上面代码的输出(以下为第一种情况下的,即构造函数不返回对象)

console.log(f1.prototype)  //undefine
//f1为实例对象,不存在prototype,prototype为函数特有

console.log(f1.__proto__) //{ sayName: [Function (anonymous)] }
console.log(f1.__proto__===F.prototype) // true
//实例对象的__proto__指向构造函数的原型 ---源于new中第二步

console.log(f1.constructor) //[Function: F]
console.log(f1.hasOwnProperty('constructor')) //false
console.log(F.prototype.hasOwnProperty('constructor')) //true
//实例对象本身不存在constructor属性,而是通过__proto__(指向F.prototype)在原型链到其构造函数的原型中找到的 ---源于new中第二步

console.log(f1.hasOwnProperty('name')) //true
//在执行构造函数中的赋值而来 ---源于new中第三步

console.log(F.prototype.constructor.hasOwnProperty('prototype')) //true
//说明构造函数中有prototype,prototype也有指向constructor

最后我们来一副图来搞清楚f1和F中的关系(该图来源于(17条消息) 帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)_码飞_CC的博客-CSDN博客_js prototype)(不懂的可以到该文章继续学习!!!)

constructor继承