摘要:原文博客地址另一篇轉(zhuǎn)載的從初級(jí)往高級(jí)走系列原型定義原型是對象的一個(gè)屬性,它定義了構(gòu)造函數(shù)制造出的對象的公共祖先。
原文博客地址:https://finget.github.io/2018/09/13/proto/原型另一篇轉(zhuǎn)載的JavaScript從初級(jí)往高級(jí)走系列————prototype
定義: 原型是function對象的一個(gè)屬性,它定義了構(gòu)造函數(shù)制造出的對象的公共祖先。通過該構(gòu)造函數(shù)產(chǎn)生的對象,可以繼承該原型的屬性和方法。原型也是對象。
用一張圖簡單解釋一下定義。
每個(gè)函數(shù)上面都有一個(gè)原型屬性(prototype),這個(gè)屬性會(huì)指向構(gòu)造函數(shù)的原型對象(Person.prototype)
每個(gè)函數(shù)的原型對象(Person.protorype)默認(rèn)都有一個(gè)constructor屬性指向構(gòu)造函數(shù)本身(Person)
每個(gè)實(shí)例都有一個(gè)隱式原型(__proto__)指向構(gòu)造函數(shù)的原型對象(Person.prototype)
每個(gè)原型對象也有隱式原型(__proto__)
// 構(gòu)造函數(shù) function Person() { this.LastName = "zhang" } // Person.prototype --- 原型 (自帶的,當(dāng)定義了構(gòu)造函數(shù),它就孕育而生了) // Person.prototype = {} --- 原型對象 是祖先 Person.prototype.name = "xiaoming"; var person = new Person() var person1 = new Person() console.log(person.name); // xiaoming (它自己沒有,就會(huì)到原型(祖先)上去找) console.log(person1.LastName); // zhang (它自己有,就會(huì)取自身的)constructor
function Person() { } var person = new Person() console.log(person.constructor) // function Person() {} // person自己沒有constructor,所以繼承至原型
Person.prototype:
圖中淺紫色的都是自帶的
function Person() { } function Car() { } Person.prototype.constructor = Car; // 改變constructor var person = new Person() console.log(person.constructor) // function Car() {}proto
// __proto__ function Person() { } Person.prototype.name = "zhangsan" var person = new Person() console.log(person.__proto__)new
New的過程
聲明一個(gè)中間對象
將中間對象的原型指向構(gòu)造函數(shù)的原型
將構(gòu)造函數(shù)的this指向中間對象
返回中間對象,即實(shí)例對象
JavaScript —— New
function DNew() { // var obj = {}; // var obj = new Object() 創(chuàng)建一個(gè)空對象 // var obj = Object.create(null); Constructor = [].shift.call(arguments); // 獲取第一個(gè)參數(shù)即構(gòu)造函數(shù) // obj.__proto__ = Constructor.prototype; var obj = Object.create(Constructor.prototype); var result = Constructor.apply(obj, arguments); return typeof result === "object" ? result || obj : obj; // 返回對象 }
在通過new 一個(gè)實(shí)例對象時(shí): function Person() { var this = { __proto__ : Person.prototype } }
person.__proto__ 與 Person.prototype是指向同一個(gè)內(nèi)存地址,這也就是 為什么實(shí)例沒有屬性或方法會(huì)到原型上去查找
function Person() { } Person.prototype.name = "zhangsan" var person = new Person() Person.prototype.name = "lisi" console.log(person.name) // ???
function Person() { } Person.prototype.name = "zhangsan" var person = new Person() Person.prototype = { name : "lisi" } console.log(person.name) // ???原型鏈
先扔一張圖:
Person.prototype.__proto__ : Object.prototype
例子:
function Grand() { } Grand.prototype.lastName = "zhang" var grand = new Grand() function Father() { } Father.prototype = grand // Father的原型指向grand對象 var father = new Father() function Son() { } Son.prototype = father // Son的原型指向father var son = new Son()
上圖中紅線表示的就是原型鏈了Object.create()
// Object.create(原型) var obj = {name: "zhang",age: 23} var obj1 = Object.create(obj) Person.prototype.name = "zhang" function Person() {} var person = Object.create(Person.prototype)
Object.create(null),null就是一個(gè)空對象,沒有原型。這也是·typeof null == "object"的原因toString
undefined和null沒有toString()
true.toString() "abc".toString() var num = 123 num.toString() // 123.toString() 試一試會(huì)怎樣 var obj = {} obj.toString() // "[object Object]"
toString來自哪??
var num = 123 // num.toString(); --> new Number(num).toString() // Number重寫 toString Number.prototype.toString = function() {} // Number.prototype.__proto__ = Object.prototype
function Person(){} Person.prototype.toString = function () { return "重寫toString" } var person = new Person() person.toString() // "重寫toString" // Object.prototype.toString // Number.prototype.toString // Array.prototype.toString // Boolean.prototype.toString // String.prototype.toString
toString隱藏功能:判斷變量、對象的類型
function Person(name, age) { this.name = name this.age = age } var person = new Person("zhang", 23) var obj = {} Person.call(obj,"wang",30) // this指向obj // obj = {age:30,name:"wang"}
call/apply不僅改變了this的指向,還會(huì)執(zhí)行對應(yīng)的方法
var cat = { name: "咪咪" } function beatTheMonster(){ console.log(this.name); } beatTheMonster.call(cat); // 1.call 改變了this的指向。改變到了cat上。 // 2.beatTheMonster函數(shù)/方法執(zhí)行了 // 3.bind(),保存了方法,并沒有直接調(diào)用它最后
創(chuàng)建了一個(gè)前端學(xué)習(xí)交流群,感興趣的朋友,一起來嗨呀!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/99509.html
摘要:采用二八定律,主要涉及常用且重要的部分。對象是當(dāng)前模塊的導(dǎo)出對象,用于導(dǎo)出模塊公有方法和屬性。箭頭函數(shù)函數(shù)箭頭函數(shù)把去掉,在與之間加上當(dāng)我們使用箭頭函數(shù)時(shí),函數(shù)體內(nèi)的對象,就是定義時(shí)所在的對象,而不是使用時(shí)所在的對象。 ES6 原文博客地址:https://finget.github.io/2018/05/10/javascript-es6/ 現(xiàn)在基本上開發(fā)中都在使用ES6,瀏覽器環(huán)境...
摘要:之所以是單線程,取決于它的實(shí)際使用,例如不可能同添加一個(gè)和刪除這個(gè),所以它只能是單線程的。所以,這個(gè)新標(biāo)準(zhǔn)并沒有改變單線程的本質(zhì)。 原文博客地址:https://finget.github.io/2018/05/21/async/ 異步 什么是單線程,和異步有什么關(guān)系 什么是event-loop 是否用過jQuery的Deferred Promise的基本使用和原理 介紹一下asyn...
摘要:原文博客地址如何理解如何實(shí)現(xiàn)是否解讀過的源碼與框架的區(qū)別實(shí)現(xiàn)實(shí)現(xiàn)獨(dú)立初始化實(shí)例兩者的區(qū)別數(shù)據(jù)和視圖的分離,解耦開放封閉原則,對擴(kuò)展開放,對修改封閉在中在代碼中操作視圖和數(shù)據(jù),混在一塊了以數(shù)據(jù)驅(qū)動(dòng)視圖,只關(guān)心數(shù)據(jù)變化, 原文博客地址:https://finget.github.io/2018/05/31/mvvm-vue/ MVVM 如何理解 MVVM 如何實(shí)現(xiàn) MVVM 是否解讀過 ...
摘要:當(dāng)中的一些元素需要更新屬性,而這些屬性只是影響元素的外觀,風(fēng)格,而不會(huì)影響布局的,比如。則就叫稱為重繪。 原文博客地址:https://finget.github.io/2018/05/22/virtualDom/ 什么是虛擬DOM 用JS模擬DOM結(jié)構(gòu) DOM變化的對比,放在JS層來做(圖靈完備語言) 提高重繪性能 重繪和回流 頁面渲染過程:showImg(https://seg...
摘要:后續(xù)我將推出進(jìn)階系列,一方面是一個(gè)監(jiān)督自己學(xué)習(xí)的一個(gè)過程,另一方面也會(huì)給看到的童鞋一些啟發(fā)。第二步鏈接到原型中現(xiàn)在把構(gòu)造函數(shù)和參數(shù)都打印出來了。 原文:https://zhehuaxuan.github.io/... 作者:zhehuaxuan 寫在前面的話 前端的入門相對簡單,相對于其他方向天花板可能會(huì)相對較低。但是在市場上一個(gè)優(yōu)秀的前端依舊是很搶手的。能夠站在金字塔上的人往往寥寥...
閱讀 3483·2019-08-30 13:15
閱讀 1423·2019-08-29 18:34
閱讀 853·2019-08-29 15:18
閱讀 3505·2019-08-29 11:21
閱讀 3281·2019-08-29 10:55
閱讀 3730·2019-08-26 10:36
閱讀 1896·2019-08-23 18:37
閱讀 1854·2019-08-23 16:57