例項識別:
建構函式模式中擁有了類和例項的概念,並且例項和例項之間是相互獨立開的
function createjsperson(name, age)
createjsperson.prototype.writejs = function()
基於建構函式模式的原型模式解決了,方法或者屬性共有的問題,想讓誰共有就把他放在createjsperson.prototype上即可
prototype
每乙個函式資料型別(普通函式,類)都有乙個天生自帶的屬性:prototype(原型),並且這個屬性是乙個物件資料型別的值
constructor
並且在prototype上瀏覽器天生給它加了乙個屬性constructor(建構函式),屬性值是當前函式(類)本身
_ proto _
每乙個物件資料型別(普通的物件,例項,prototype..)也天生自帶乙個屬性: _ _proto _ _,屬性值是當前例項所屬類的原型(prototype)
function fn()
fn.prototype.getx = function()
var f1 = new fn;
var f2 = new fn;
console.log(fn.prototype.constructor === fn); // true
console.log(f1 instanceof object); // true
通過 物件名.屬性名 的方式獲取屬性值的時候, 首先在物件的私有的屬性上進行查詢, 如果私有中存在這個屬性,則獲取的是私有的屬性值;
如果私有的沒有,則通過__proto__找到所屬類的原型, 類的原型上定義的屬性和方法都是當前例項公有的屬性和方法, 原型上存在的話, 獲取的是共有的屬性值;
如果原型上也沒有,則繼續通過原型上的__proto__繼續向上查詢, 一直找到obejct.prototype為止
console.log(f1.getx === f2.getx); // true
console.log(f1.__proto__.getx === f2.getx);// true
console.log(f1.getx === fn.prototype.getx); // true
在ie瀏覽器中,原型模式也是同樣的原理,但是ie瀏覽器怕你通過__proto__把公有的修改,禁止我們修改__proto__起別名
function fn()
var pro = fn.prototype;
pro.getx = function(){}
pro.gety = function(){}
重構原型物件的方式
function fn()
fn.prototype = ,
gety: function(){}
}var f = new fn;
console.log(f.constructor)' // object
只有瀏覽器天生給fn.prototype開闢的堆記憶體裡面才有constructor,而我們自己開闢的這個堆記憶體沒有這個屬性,這樣constructor指向就不再是fn而是object
為了和原來的保持一致,我們需要手動的增加constructor的指向
fn.prototype =
會把之前已經存在於原型上的屬性和方法給替換掉, 用這種方式修改內建類的話, 瀏覽器會給遮蔽掉
array.prototype =
}console.dir(array.prototype);
但是可以使用prototype屬性,乙個個修改內建的方法,如果方法名和原來內建的重複了, 會把內建的修改掉, 在內建類的原型上增加方法, 名命都需要加特殊的字首
array.prototype.sort = function()
var ary = [1, 2, 2, 1, 2, 3, 4];
ary.sort();
console.log(ary);
for in 循壞在遍歷的時候, 可以把自己私有的和在它所屬原型上擴充套件的屬性和方法都遍歷到.
object.prototype.aaa = function(){};
var obj = ;
for(let key in obj)
可以使用以下方法,進行判斷處理
for(let key in obj)
}for(let key in obj)
}
建立乙個新的物件, 但是要把proobj作為這個物件的原型, 在ie6-ie8不相容(ecmascript5)
var obj =
}var obj2 = object.create(obj)
console.dir(obj2)
obj.gety = function(){}
console.dir(obj2)
自己實現乙個create
var obj =
}function object(o)
fn.prototype = o;
return new fn();
}var newobj = object(obj);
原型繼承是js中最常用的一種繼承方式, 子類b想要繼承父類a中的所有的屬性和方法(私有+公有), 只需要讓b.prototype = new a;
特點: 它是把父類中的私有+公有的都繼承到了子類原型上(共有的)
核心: 原型繼承並不是把父類中的屬性和方法轉殖乙份一模一樣的給b,而是讓b和a之間增加了原型鏈的連線, 以後b的例項n想要a中的getx方法,需要一級一級的向上查詢來使用
function a()
a.prototype.getx = function()
function b()
b.prototype = new a
缺點: 不安全, 可以通過子類或子類的例項,更改父類原型鏈上的屬性和方法, 對a的例項和子類造成影響
var b = new b
var a = new a
b.__proto__.__proto__.getx = 3000;
console.log(a.getx)
b.prototype.__proto__.getx = 2000;
console.log(a.getx)
借用建構函式, 偽造物件繼承和經典繼承
call:呼叫乙個物件的乙個方法,用另乙個物件替換當前物件。例如:b.call(a, args1,args2);即a物件呼叫b物件的方法。
function a()
a.prototype.getx = function()
function b()
var b = new b;
console.log(b.x)
缺點:
父類在原型鏈中定義的函式不能被子類訪問,也就是說所有的函式都必須寫在建構函式內部,無法復用
把父類私有和公有的屬性和方法,轉殖乙份一模一樣的給子類私有的
function a()
a.prototype.getx = function()
function b()
}var b = new b;
console.log(b.x)
子私有 = 父私有, 子公有 = 父私有 + 父公有
function a()
a.prototype.getx = function()
function b()
b.prototype = new a;
b.prototype.constructor = b;
var b = new b;
console.log(b.x)
子私有 = 父私有, 子公有 = 父公有
function a()
a.prototype.getx = function()
function b()
b.prototype = object.create(a.prototype);
b.prototype.constructor = b;
var b = new b;
console.log(b.x)
function **gfn())
arguments.pop()
arguments.shift()
return eval(arguments.join("+")) / arguments.length;
}**gfn(10, 20 ,30 ,10 ,30, 40, 40); // 26
JS 聖杯模式(原型鏈繼承)
聖杯模式 為了son繼承father原型上的東西,還可以修改自己原型上的東西,對father原型不影響。function inherit target,origin 函式f作為乙個中間層,上連father,下連son,使兩函式互不干擾 f.prototype origin.prototype tar...
JS原型鏈模式
例項識別 建構函式模式中擁有了類和例項的概念,並且例項和例項之間是相互獨立開的 function createjsperson name,age createjsperson.prototype.writejs function 基於建構函式模式的原型模式解決了,方法或者屬性共有的問題,想讓誰共有就...
JS學習之原型和原型鏈模式
原型鏈模式 1 每乙個物件 例項也是物件 都有乙個天生自帶的屬性 proto 這個屬性指向當前所屬類的原型 prototype 2 每乙個函式 類也是函式 都有乙個天生自帶的屬性 prototype 原型 並且這個屬性儲存的值是乙個物件資料型別的資料,瀏覽器預設給這個屬性開闢乙個堆記憶體 在這個堆記...