談談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指向複製程式碼