JS的prototype和__proto__(含es6的class)

JS的prototype和__proto__(含es6的class)css

1、prototype和__proto__的概念

prototype是函數的一個屬性(每一個函數都有一個prototype屬性),這個屬性是一個指針,指向一個對象。它是顯示修改對象的原型的屬性。
__proto__是一個對象擁有的內置屬性(請注意:prototype是函數的內置屬性,__proto__是對象的內置屬性),是JS內部使用尋找原型鏈的屬性。es6

用chrome和FF均可以訪問到對象的__proto__屬性,IE不能夠。

2、new 的過程

var Person = function(){};
var p = new Person();

new的過程拆分紅如下三步:chrome

(1) var p={}; 也就是說,初始化一個對象p
(2) p.__proto__ = Person.prototype;
(3) Person.call(p); 也就是說構造p,也能夠稱之爲初始化p

關鍵在於第二步,咱們來證實一下:函數

var Person = function(){};
var p = new Person();
alert(p.__proto__ === Person.prototype);

這段代碼會返回true。說明咱們步驟2是正確的。測試

3、示例

var Person = function(){};
    Person.prototype.sayName = function() {
        alert("My Name is Jacky");
    };
    Person.prototype.age = 27;
    var p = new Person();
    p.sayName();

p是一個引用指向Person的對象。咱們在Person的原型上定義了一個sayName方法和age屬性,當咱們執行p.age時,會先在this的內部查找(也就是構造函數內部),若是沒有找到而後再沿着原型鏈向上追溯。這裏的向上追溯是怎麼向上的呢?這裏就要使用__proto__屬性來連接到原型(也就是Person.prototype)進行查找。最終在原型上找到了age屬性。this

我的聯繫筆記(純粹我的好理解的寫法)
console.log('測試')
class css {
  constructor(dd) {  this.dd = '33333333333';  }
  rr() {   return 'rr'  }
}
class aa extends css {
  constructor() {
    super() //extends的類裏使用constructor必需要有super
    this.b = this.b.bind(this);
    this.dd = '2222222222222'  }
  b() {    return 'ceshi'  }
  c() {  return this.dd }//dd被修改   // return this  b:function ()   dd:"2222222222222"
}
const bb = new aa()
// 上一個自身(constructor):__proto__ ; 本身:prototype 口訣:aa.__proto__.prototype
// aa的上一個自身的本身===上一個的本身
// ★★★★ 類裏的__proto__找的是父級的constructor,類裏的__proto__.prototype找的是父級的本身(父級.prototype)
// ★★★★ 實例對象的__proto__找的是父級的本身,即父級.prototype
console.log('-----------------------------------------') //
console.log('aa', aa) //
console.log('css', css) //
console.log('css.prototype', css.prototype) // 指向自身
console.log('css.prototype.__proto__', css.prototype.__proto__) // 指向自身
console.log('css.__proto__', css.__proto__) //function () { [native code] }
console.log('css.__proto__.__proto__', css.__proto__.__proto__) //
console.log('aa.__proto__', aa.__proto__) //  指向css的constructor aa.__proto__===css
console.log('aa.prototype', aa.prototype) //  指向自身
console.log('aa.__proto__.prototype', aa.__proto__.prototype) // 指向css的自身  aa.__proto__.prototype===css.prototype===aa.prototype.__proto__
console.log('aa.prototype.__proto__', aa.prototype.__proto__) // 同上
console.log('-----------------------------------------') //
console.log('bb', bb) // 指向aa的constructor, bb即aa的實例對象
console.log('bb.__proto__', bb.__proto__) //  指向父級自身即aa.prototype  bb.__proto__===aa.prototype
console.log('bb.prototype', bb.prototype) //  undefined
console.log('bb.__proto__.__proto__', bb.__proto__.__proto__) // 指向css本身 bb.__proto__.__proto__css.prototype 
console.log('bb.__proto__.__proto__.__proto__', bb.__proto__.__proto__.__proto__) // bb.__proto__.prototype===aa.__proto__.prototype===css.prototype===aa.prototype.__proto__
console.log('bb.__proto__.__proto__.__proto__.__proto__', bb.__proto__.__proto__.__proto__.__proto__) // null
console.log('bb.__proto__.prototype', bb.__proto__.prototype) // undefined, 已是自身了
// console.log('bb.prototype.__proto__',bb.prototype.__proto__) //  err
console.log('-----------------------------------------') //
// const aaa = () => '1234567'
// console.log(aaa()) (()=>{a}) // 等價於 (function () {   a; }); ()=>(a) // 等價於
// (function () {   return a; });
console.log('********************************')
var Person = function(){ return 222;};
Person.prototype.sayName = function() {   return 'cs'};
Person.prototype.age = 27;
var p = new Person();
p.__proto__.cs = 'cs'; //在Person.prototype裏添加了cs='cs'
console.log('Person',Person)  //Person function (){return 222}
console.log('Person.prototype',Person.prototype) //person本身
console.log('Person.prototype.__proto__',Person.prototype.__proto__)  //Person.prototype.__proto__===Person.__proto__.__proto__===p.__proto__.__proto__
console.log('Person.__proto__',Person.__proto__) //function () { [native code] }
console.log('Person.__proto__.__proto__',Person.__proto__.__proto__)
console.log('p',p) // {}
console.log('p.prototype',p.prototype) //undefined
console.log('p.__proto__',p.__proto__)  //p.__proto__===Person.prototype
console.log('p.__proto__.__proto__',p.__proto__.__proto__)  //p.__proto__.__proto__ ==Person.__proto__.__proto__===Person.prototype.__proto__
console.log('********************************')
測試結果:

春雷原創:http://www.cnblogs.com/chunlei36prototype

相關文章
相關標籤/搜索