js原型那點簡單事

找抽的小陀螺發表於2017-09-23

談談js原型那些事

先來說說原型prototype概念: 在百度詞條中意思是指原來的型別或模型 按照這個意思是說 物件的原型是物件模子 模子有的特性物件都有 感覺有點像拷貝的意思 在JavaScript中物件的建立不存在拷貝 物件的原型其實也是物件 二者是獨立存在的

Function Object 都是JavaScript自帶內建物件

prototype (每一個函式資料型別 )每個函式都有一個prototype屬性 這個屬性是物件資料型別 代表了函式的原型

  function c () {}   // 函式c
  console.log(c.prototype)   //顯示constructor: c()     __proto__: Object  這裡顯示兩個函式的prototype 有兩個屬性  constructor 指向了c    一個_proto_複製程式碼

在JavaScript中 萬物都是物件 但是物件也有區別 分為普通物件 函式物件
函式物件: new Function 建立的物件都是函式物件 其他都是普通物件
這些跟原型有毛關係嗎

原型就是建構函式的一個普通例項物件

proto (每一個物件資料型別) 沒有物件天生自帶了一個屬性 屬性值(proto)屬性值是當前例項所屬的原型

  var c = {}
  console.log(c)   //函式__proto__: Object複製程式碼

先來看下JavaScript 中一個類在new出來具體過程

 var Person = function(name) {
    this.name = name; 
 } // Person可以看成java中的類  下面我們要new出來這個類
   var a = new Person()  //這個是我們常見的  初始化物件a

   var a = {}; // 建立一個空的
   a._proto_ = Person.prototype //將 指向Person原型
   Person.call(a)  //改變this

   //上面這兩種方式建立一個物件是一樣的效果複製程式碼

對上面的 a.proto === Person.prototype // true
在JavaScript中每個資料物件型別 物件都有一個proto屬性當我們訪問一個物件的屬性時 如果這個物件內部不存在這個屬性 那麼他就會去 proto 裡找這個屬性 這個 proto 又會有自己的 proto 於是就這樣一直找下去 也就是我們平時所說的原型鏈的概念。

上一個簡單的code來理解物件的proto

 var Person = function() {};
 Person.prototype.showname = function() {
   console.log("_proto_");
 }
var p = new Person();
p.showname(); // _proto_複製程式碼

這個很簡單大家都會(試想下為啥p 能方位showname) 下面將他演變一下

 var Person = function () {};
 Person.prototype.showname = function() {
   console.log("_proto_");
 }

 var  p = {};
 p._proto_ = Person.Prototype;
 Person.call(p);
 console.log(p.showname()) //??   答案是_proto_複製程式碼

這個時候我們呼叫p.showname() 在p 上肯定是沒有showname的方法了 於是到 p 的 proto 屬性中去找,也就是 Person.prototype 而我們定義了 Person.prototype.showname=function(){} 於是 p 在 Person.prototype 中就找到了這個方法

接下來在看個code

var Person = function() {};
Person.prototype.say = function() {
    console.log("Person say");
}
Person.prototype.salary = 50000;

var Programmer = function() {};
Programmer.prototype = new Person();
Programmer.prototype.writeCode = function() {
    console.log("Programmer writes code");
};
Programmer.prototype.salary = 500;

var p = new Programmer();
p.say(); // Person say
p.writeCode(); // Programmer writes code
console.log(p.salary); // 500複製程式碼

有點懵嗎 下面開始一步步說下

var Person = function() {};
Person.prototype.say = function() {
    console.log("Person say");
}
Person.prototype.salary = 50000;

var Programmer = function() {};複製程式碼

程式碼到這裡大家都能看的懂

Programmer.prototype = new Person();  //進行到這句話的時候 實際上做了一件事這句等同下面 

前面說話 new的過程下面試著演變下
Programmer.prototype = {};
Programmer.prototype._ptoto_ = Person.prototype;
Person.call(Programmer.prototype);複製程式碼

到這裡清楚了嗎 接著走

var p = new Programmer();
p.say(); // Person say
p.writeCode(); // Programmer writes code
console.log(p.salary); // 500   

將這裡也演變下
var p = {};
p._proto_ = Programmer.prototype;
p._proto_ = new Person();
p._proto_ = Person.rototype
Person.call(p.__proto__);
Programmer.call(p);複製程式碼

其實這就是原型鏈的產生

這其實就是new 的一個過程 在回顧下 這個過程

var Person = function(name) {
    this.name = name;
}

// 初始化一個物件 p
var p = new Person();


// var p = {};  // 建立一個空的物件
// p.__proto__ =  Person.prototype;  //設定原型
// Person.call(p);  //改變this指向複製程式碼

參考資料:關於proto和prototype的一些理解

相關文章