摘要:原文鏈接關于的原型和原型鏈,看我就夠了一參考鏈接闖關記之原型及原型鏈之原型與原型鏈一篇文章帶你理解原型和原型鏈徹底理解原型鏈一的默認指向圖解和的三角關系原型和原型鏈三張圖搞懂的原型對象與原型鏈
溫故 創建對象的三種方式
通過對象直接量
通過new創建對象
通過Object.create()
js中對象分為兩種函數對象
普通對象
仔細觀察如下代碼
function Foo(name) { this.name = name; } var foo = new Foo("陌上寒"); console.log(foo)// Foo{name: "陌上寒"} //--------------- var foo1 = {name:""陌上寒""} //等價于 var foo1 = new Object() foo1.name = "陌上寒"
綜合以上,得出結論==>普通對象都是通過函數創建的
prototype每一個函數對象都有一個prototype屬性,但是普通對象是沒有的;
遺留問題昨天留下了一些知識點,今天重點討論
constructor
_proto_
知新 constructor構造函數我們昨天說創建對象的三種方式,第二種是通過new創建對象,
var obj = new Object()//創建一個空對象等同于 var obj = {} console.log(obj.constructor===Object)//true
Object就是一個構造函數,是js內置的構造函數,上面的例子中Object就是obj的構造函數,這個例子似乎不太明顯,我們繼續看
function Foo(name){ this.name = name } var foo = new Foo("陌上寒") console.log(foo.constructor===Foo)//true
我們自定義了一個構造函數Foo,Foo是foo的構造函數,foo的構造函數就是Foo
構造函數與其他函數的唯一區別,就在于調用它們的方式不同。不過,構造函數畢竟也是函數,不存在定義構造函數的特殊語法。任何函數,只要通過 new 操作符來調用,那它就可以作為構造函數;而任何函數,如果不通過 new 操作符來調用,那它跟普通函數也不會有什么兩樣。
構造函數在創建時有一個約定,如果是構造函數,那么首字母要大寫,普通函數首字母小寫
constructor和我們昨天討論的prototype有什么聯系嗎?
觀察如下代碼的輸出
function Foo(name) { this.name = name; } var foo = new Foo("陌上寒"); console.log(Foo.prototype)
通過昨天的討論我們得知只有函數對象才存在prototype
輸出
Foo.prototype是Foo的原型對象
繼續觀察
function Foo(name) { this.name = name; } var foo = new Foo("陌上寒"); console.log(Foo.prototype.constructor===Foo)//true
在默認情況下,所有原型對象都會自動獲得一個 constructor(構造函數)屬性,這個屬性包含一個指向 prototype 屬性所在函數的指針。就拿前面的例子來說,Foo.prototype.constructor 指向 Foo。
我們得出以下結論
原型對象中的constructor屬性,指向該原型對象對應的構造函數
也就是說上面的例子,Foo的原型對象是Foo.prototype,原型對象(Foo.prototype)中有一個constructor屬性,這個constructor屬性指向原型對象(Foo.prototype)對應的構造函數Foo,用一行代碼概括
console.log(Foo.prototype.constructor===Foo)//true
以上就是constructor和prototype的關系
我們注意到原型對象(Foo.prototype)中還存在一個屬性__proto__,這又是什么?它和prototype,constructor又有什么關聯呢?
那么__proto__是什么?每個對象都會在其內部初始化一個屬性,就是__proto__。
Firefox、Safari 和 Chrome 的每個對象上都有這個屬性 ,而在其他瀏覽器中是完全不可見的(為了確保瀏覽器兼容性問題,不要直接使用 _proto_ 屬性,此處只為演示)。我們繼續看代碼
var arr = new Array() console.log(arr.__proto__===Array.prototype);//true var str = new String() console.log(str.__proto__===String.prototype);//true var Fun = new Function() console.log(Fun.__proto__===Function.prototype);//true var bool = new Boolean console.log(bool.__proto__===Boolean.prototype);//true var obj = new Object() console.log(obj.__proto__===Object.prototype);//true function MyFun() { console.log("我是陌上寒"); } var myfoo = new MyFun() console.log(myfoo.__proto__===MyFun.prototype);//true
再重復一次:Array,String,Function,Boolean,Object都是js內置的構造函數,MyFun是自定義的構造函數
只有函數對象才存在prototype
所有對象(除了Object.prototype)都存在_proto_
剛才我們討論過,普通對象都是通過函數創建的
根據以上我們得出結論:
普通對象__proto__指向當前函數對象的原型,
你可能發現了,有一個矛盾的地方,所有對象都存在__proto__,只有普通對象的__proto__指向當前函數對象的原型,那函數對象的__proto__指向哪里呢?繼續看代碼
function MyFun() { console.log("我是陌上寒"); } console.log(Boolean.__proto__);//? () { [native code] } console.log(Function.__proto__);//? () { [native code] } console.log(String.__proto__);//? () { [native code] } console.log(Array.__proto__);//? () { [native code] } console.log(Object.__proto__);//? () { [native code] } console.log(MyFun.__proto__);//? () { [native code] }
函數對象的__proto__輸出的都是? () { [native code] }
函數內部是[native code],也就是系統編譯好的二進制代碼函數,我們不對此做研究
上面說到,所有對象都有__proto__,原型對象也是對象,
我們得出結論
原型對象也存在_proto_
結合以上我門又一次得出結論
原型對象的__proto__指向當前函數對象的原型,
還是繼續看代碼,便于理解*
console.log("陌上寒".__proto__===String.prototype);//true console.log(String.prototype.__proto__===Object.prototype);//true //等量代換,得出一下結論 console.log("陌上寒".__proto__.__proto__===Object.prototype);//true //自此形成了一條鏈,===>原型鏈
解釋一下如上代碼,
"陌上寒"是字符串類型,"陌上寒"的構造函數是String(), 所以"陌上寒"的__proto__指向String的原型
String()是js的內置構造函數,繼承自Object,也就是說Object是頂端,是原型鏈的頂端,既然是頂端,所以:
console.log(Object.prototype.__proto__)//null
Object的原型對象是不存在__proto__的
總結所有對象(不包括Object.prototype)有__proto__屬性,函數對象有prototype屬性;
對象由函數生成;
生成對象時,對象的__proto__屬性指向當前函數的prototype屬性。
Object.prototyp處于原型鏈的頂端,不存在原型,不繼承任何屬性,其他原型對象都是普通對象,普通對象都具有原型,所有的內置構造函數(以及大部分自定義構造函數)都具有一個繼承自Object.prototype的原型,例如Date.prototype的 屬性繼承自Object.prototype,因此有new Date()創建的Date對象的屬性同時繼承自Date.prototype和Object.prototype,這一系列的原型對象就是所謂的原型鏈。
原文鏈接
關于javascript的原型和原型鏈,看我就夠了(一)
參考鏈接
《JavaScript 闖關記》之原型及原型鏈
JavaScript之原型與原型鏈
一篇文章帶你理解原型和原型鏈
徹底理解JavaScript原型鏈(一)—__proto__的默認指向
圖解prototype、proto和constructor的三角關系
Object.prototype 原型和原型鏈
三張圖搞懂JavaScript的原型對象與原型鏈
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/98978.html
摘要:要用作原型的對象。函數對象可以創建普通對象,這個我們上面講過了回顧一下這是一個自定義構造函數普通對象沒法創建函數對象,凡是通過創建的對象都是函數對象,其他都是普通對象通常通過創建,可以通過來判斷。 關于js的原型和原型鏈,有人覺得這是很頭疼的一塊知識點,其實不然,它很基礎,不信,往下看要了解原型和原型鏈,我們得先從對象說起 創建對象 創建對象的三種方式: 對象直接量 通過對象直接量創建...
摘要:對于中的引用類型而言,是保存著它們所有實例方法的真正所在。高級程序設計構造函數陌上寒原型對象有一個屬性,指向該原型對象對應的構造函數為什么有屬性那是因為是的實例。 溫故 我們先回顧一下前兩天討論的內容 創建對象的三種方式 通過對象直接量 通過new創建對象 通過Object.create() js中對象分為兩種 函數對象 普通對象 原型對象prototype 每一個函數對象都...
摘要:基本概念方法會返回一個布爾值,指示對象自身屬性中非繼承屬性是否具有指定的屬性,如果具有帶指定名稱的屬性,則方法返回,否則返回。此方法不會檢查對象原型鏈中的屬性該屬性必須是對象本身的一個成員。使用語法參數,必需。 hasOwnProperty基本概念 hasOwnProperty() 方法會返回一個布爾值,指示對象自身屬性中(非繼承屬性)是否具有指定的屬性,如果 object 具有帶指定...
摘要:也就是說,所有的函數和構造函數都是由生成,包括本身。如果只考慮構造函數和及其關聯的原型對象,在不解決懸念的情況下,圖形是這樣的可以看到,每一個構造函數和它關聯的原型對象構成一個環,而且每一個構造函數的屬性無所指。 前言 JavaScript 是我接觸到的第二門編程語言,第一門是 C 語言。然后才是 C++、Java 還有其它一些什么。所以我對 JavaScript 是非常有感情的,畢...
閱讀 3206·2021-11-19 09:40
閱讀 3005·2021-09-09 09:32
閱讀 792·2021-09-02 09:55
閱讀 1393·2019-08-26 13:23
閱讀 2403·2019-08-26 11:46
閱讀 1229·2019-08-26 10:19
閱讀 2054·2019-08-23 16:53
閱讀 1072·2019-08-23 12:44