深度剖析javascript的面向对象

时间:2022-02-06 15:58:30

最近看《你不知道的javascript》一书,在this指向那一章有说过new关键字执行的四部曲

  1. 创建一个对象
  2. 执行[[prototype]]连接
  3. 绑定函数this到该对象
  4. 如果函数无返回值默认返回该对象

以及在后面描述对象的章节中说的

javascript一直在模拟对象的行为,而作者更愿意以“委托”来看待javascript中原型链的连接作用

突然感觉自己学了一年假的javascript有木有

先来说说这个骗了我这么久的new关键字,为了方便解读new关键字的四部曲,毕竟博主也是想了半天才明白着四步做了什么,所以给出一个简陋的实现步骤

// 这是我们正常的‘面向对象’的写法
function Obj(){
this.name = "whiteG"
}
Obj.prototype.getName = function(){
console.log(this.name)
}
var O = new Obj();
O.getName(); // whiteG



// 模拟上面四步曲
function Obj1(){
this.name = "whiteG"
}
// 第一步,创建一个新对象
var o = {};

// 第二步,执行[[prototype]]连接,[[prototype]]这个是内部属性,只能通过__proto__属性间接访问
o.__proto__ = Obj1.prototype;

// 第三步,绑定this到该对象
Obj1.call(o);

// 第四步返回对象就不用了,我们直接使用o对象看看
// Obj1的prototype添加方法
Obj1.prototype.getName = function(){
console.log(this.name)
}

上面就是简单的还原new关键字的真实欺骗性啊,不过博主有过好奇

o.__proto__ = Obj1.prototype;   // 没毛病
o.__proto__ = Obj1.p; // 在给Obj1.p添加方法就会有问题报错 Obj1.p是空

// 试试看
console.log(typeof Obj1.prototype) // object !!

然后想起了经常听见的一句话,任何对象都有个内置的[[prototype]],其实也有个“点prototype”属性,自带“点prototype”属性,并且该属性为一个对象,上面还有个constructor。其实这个constructor属性也就是一个指向该函数的指针!这也就是为什么那些通过原型继承的方式需要手动将proototype.constructor指回所谓的构造函数。

这就是javascript从开始到现在下的一大盘棋

至于为什么能通过prototype以及[[prototype]]委托起来的对象访问到属性就涉及到属性访问会通过[[Get]]方法去查询。(下次聊这玩意)