首頁 > web前端 > js教程 > 主體

JS原型鏈詳解

小云云
發布: 2018-03-13 14:54:09
原創
2963 人瀏覽過

本文主要跟大家分享JS原型鏈詳解,函數(Function)才有prototype屬性,物件(除Object)擁有__proto__。希望能幫助大家。


#所謂原型鏈,指的就是圖中的proto這條指標鏈!

原型鏈的頂層就是Object.prototype,而這個物件的是沒有原型物件的。

可在chrome的控制台裡面輸入:


    Object.__proto__
登入後複製

#輸出是:

<br/>

    function Empty() {}
登入後複製

原型鏈,如此而已。

原型是一個對象,其他物件可以透過它實現屬性繼承。

一、prototype與__proto__的差異<br/>

<br/>

var a = {};
console.log(a.prototype);  //undefined
console.log(a.__proto__);  //Object {}

var b = function(){}
console.log(b.prototype);  //b {}
console.log(b.__proto__);  //function() {}
登入後複製

<br/>

/*1、字面量方式*/
var a = {};
console.log(a.__proto__);  //Object {}

console.log(a.__proto__ === a.constructor.prototype); //true

/*2、构造器方式*/
var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}

console.log(a.__proto__ === a.constructor.prototype); //true

/*3、Object.create()方式*/
var a1 = {a:1}
var a2 = Object.create(a1);
console.log(a2.__proto__); //Object {a: 1}

console.log(a.__proto__ === a.constructor.prototype); //false(此处即为图1中的例外情况)
登入後複製

<br/>

var A = function(){};
var a = new A();
console.log(a.__proto__); //A {}(即构造器function A 的原型对象)
console.log(a.__proto__.__proto__); //Object {}(即构造器function Object 的原型对象)
console.log(a.__proto__.__proto__.__proto__); //null
登入後複製

我在寫一篇圖解prototype和__proto__的區別時,搜資料搜到了一個有意思的現象,下面這兩個運算返回的結果是一樣的:

<br/>

Function instanceof Object;//true
Object instanceof Function;//true
登入後複製

這個是怎麼一回事呢?要從運算子instanceof說起。

一、instanceof究竟是運算什麼的?

我曾经简单理解instanceof只是检测一个对象是否是另个对象new出来的实例(例如var a = new Object(),a instanceof Object返回true),但实际instanceof的运算规则上比这个更复杂。

首先w3c上有官方解释(传送门,有兴趣的同学可以去看看),但是一如既往地让人无法一目了然地看懂……

知乎上有同学把这个解释翻译成人能读懂的语言(传送门),看起来似乎明白一些了:

<br/>

//假设instanceof运算符左边是L,右边是R
L instanceof R 
//instanceof运算时,通过判断L的原型链上是否存在R.prototype
L.__proto__.__proto__ ..... === R.prototype ?
//如果存在返回true 否则返回false
登入後複製

注意:instanceof运算时会递归查找L的原型链,即L.__proto__.__proto__.__proto__.__proto__...直到找到了或者找到顶层为止。

所以一句话理解instanceof的运算规则为:

instanceof检测左侧的__proto__原型链上,是否存在右侧的prototype原型。

二、图解构造器Function和Object的关系

<br/>
登入後複製

<br/>

<br/>

我们再配合代码来看一下就明白了:<br/>

//①构造器Function的构造器是它自身
Function.constructor=== Function;//true

//②构造器Object的构造器是Function(由此可知所有构造器的constructor都指向Function)
Object.constructor === Function;//true



//③构造器Function的__proto__是一个特殊的匿名函数function() {}
console.log(Function.__proto__);//function() {}

//④这个特殊的匿名函数的__proto__指向Object的prototype原型。
Function.__proto__.__proto__ === Object.prototype//true

//⑤Object的__proto__指向Function的prototype,也就是上面③中所述的特殊匿名函数
Object.__proto__ === Function.prototype;//true
Function.prototype === Function.__proto__;//true
登入後複製

三、当构造器Object和Function遇到instanceof

我们回过头来看第一部分那个“奇怪的现象”,从上面那个图中我们可以看到:

<br/>

Function.__proto__.__proto__ === Object.prototype;//true
Object.__proto__ === Function.prototype;//true
登入後複製

所以再看回第一点中我们说的instanceof的运算规则,Function instanceof Object 和 Object instanceof Function运算的结果当然都是true啦!

如果看完以上,你还觉得上面的关系看晕了的话,只需要记住下面两个最重要的关系,其他关系就可以推导出来了:

1、所有的构造器的constructor都指向Function

2、Function的prototype指向一个特殊匿名函数,而这个特殊匿名函数的__proto__指向Object.prototype

 

至於prototype和__proto__的關係如何推導,可以參考我寫的上一篇部落格《三張圖搞懂JavaScript的原型物件與原型鏈》

本文試著闡述Js中原型(prototype)、原型鏈(prototype chain)等概念及其作用機制。上一篇文章(圖解Javascript上下文與作用域)介紹了Js中變數作用域的相關概念,實際上關注的一個核心問題是:“在執行當前這行程式碼時Js解釋器可以獲得哪些變數”,而原型與原型鏈其實還是關於這個問題。

我們知道,在Js中一切皆為物件(Object),但Js中並沒有類別(class);Js是基於原型(prototype-based)來實現的物件導向(OOP)的程式設計範式的,但並不是所有的物件都有prototype這一屬性:

<br/>

<br/>

1

2

3

4

5

6

7

8

<br/>

var a = {}; 

console.log(a.prototype);  //=>未定義

## 

#var#b = function##(){}; 

console.log(b.prototype);  

//=> {}<p class="line number6 index5 alt1" style="margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-size:12px;min-height:auto;white-space:nowrap;"> </p><p class="line number7 index6 alt2" style="margin:0px;padding:0px 1em;background:rgb(244,244,244) none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-size:12px;min-height:auto;white-space:nowrap;"><code class="javascript keyword" style="margin:0px;padding:0px;background:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-family:Consolas, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, Courier, monospace;min-height:auto;color:rgb(0,0,255);">#var#c = '你好'##; 

console.log(c.prototype);  //=>不明確的##########

prototype是每個function定義時自帶的屬性,但Js中function本身也是對象,我們先來看看下面幾個概念的差異:

1. functionFunctionObject{}

<br/>

<br/>

function

是Js的一個關鍵字,用來定義函數類型的變量,有兩種語法形式:

#################### #############1######2######3######4#######5######6# #####7######8####

9

<br/>

函數 #f1(){ 

#  console.log('這是函數f1!');

}

#### ## #######typeof######(f1);  ######//=> '功能'#########

var#f2 = function(){ 

  console .log('這是函數f2!');

##}

typeof (f2);  //=> '功能'##########

如果用更物件導向的方法定義函數,可以用Function

<br/>

<br/>

1

2

3

#4

##5

<br/>

var#f3 = newFunction("console.log('這是函數f3! '); “); 

f3();        //=> “這是函數 f3!” 

typeof(f3);  //=> '功能'#########<p class="line number5 index4 alt2" style="margin:0px;padding:0px 1em;background:rgb(244,244,244) none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-size:12px;min-height:auto;white-space:nowrap;"><code class="javascript keyword" style="margin:0px;padding:0px;background:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-family:Consolas, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, Courier, monospace;min-height:auto;color:rgb(0,0,255);">typeof(函數); //=> '功能'##########<p style="margin:10px auto;color:rgb(51,51,51);font-family:Verdana, Arial, Helvetica, sans-serif;font-size:14px;background-color:rgb(255,255,255);">實際上<code style="margin:0px;padding:0px;">Function就是一個用來建構函式類型變數的類,或者說是函數型別實例的建構子(constructor);與之相似的ObjectStringNumber等,都是Js內建型別實例的建構子。比較特殊的是Object,它用來產生物件類型,其簡寫形式為{}

<br/>

<br/>

1

2

#3

4

5

6

7

<br/>

var#o1 = new#Object(); 

typeof(o1);      //=> '物件'

 

#varo2 = {}; 

typeof(o2);     //=> '目的'#########<p class="line number7 index6 alt2" style="margin:0px;padding:0px 1em;background:rgb(244,244,244) none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-size:12px;min-height:auto;white-space:nowrap;"><code class="javascript keyword" style="margin:0px;padding:0px;background:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-family:Consolas, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, Courier, monospace;min-height:auto;color:rgb(0,0,255);">typeof(物件); //=> '功能'##########<h2 style="margin-top:20px;margin-bottom:20px;padding:0px;font-size:21px;line-height:1.5;color:rgb(51,51,51);font-family:Verdana, Arial, Helvetica, sans-serif;background-color:rgb(255,255,255);">2. <code style="margin:0px;padding:0px;">prototype VS __proto__

#清楚了上面的概念之後再來看prototype

<br/>

Each function has two properties: 

length<br/> and 

prototype

prototype

length

是每一個函數類型自帶的兩個屬性,而其它非函數類型並沒有(開頭的例子已經說明),這一點之所以比較容易被忽略或誤解,是因為所有類型的構造函數本身也是函數,所以它們自帶了

prototype

屬性:

<br/>

###############1#### ##2######3######4###################

// Node

console.log(Object.prototype);  //=> {} 

console.log(Function.prototype); //=> [功能:空]

console.log(String.prototype);  //=> [細繩: '']##########<p style="margin:10px auto;color:rgb(51,51,51);font-family:Verdana, Arial, Helvetica, sans-serif;font-size:14px;background-color:rgb(255,255,255);">除了<code style="margin:0px;padding:0px;">prototype之外,Js中的所有物件(undefinednull等特殊情況除外)都有一個內建的[[ Prototype]]屬性,指向它「父類」的prototype,這個內建屬性在ECMA標準中並沒有給出明確的獲取方式,但是許多Js的實作(如Node、大部分瀏覽器等)都提供了一個__proto__屬性來指稱這一[[Prototype]],我們透過下面的例子來說明實例中的__proto__#是如何指向建構函式的prototype的:

<br/>

<br/>

1

2

3

4

5

##6

7

# 8

9

10

11

<br/>

人= 函數(){}; 

Person.prototype.type = 'Person'

Person.prototype.maxAge = 100;

## 

var#p = new## #Person(); 

console.log(p.maxAge); 

p.name = '下雨天'#;

# Person.prototype.constructor === Person;  //=>真的 ######<p class="line number10 index9 alt1" style="margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-size:12px;min-height:auto;white-space:nowrap;"><code class="javascript plain" style="margin:0px;padding:0px;background:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-family:Consolas, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, Courier, monospace;min-height:auto;color:rgb(0,0,0);">p.__proto__ === Person.prototype;         //=> true

console.log(p.prototype);                 //=>不明確的##########<p style="margin:10px auto;color:rgb(51,51,51);font-family:Verdana, Arial, Helvetica, sans-serif;font-size:14px;background-color:rgb(255,255,255);">上面的程式碼範例可以用下圖解釋:</p><p><img src="https://img.php.cn/upload/article/000/054/025/49ab92ca686055e31fa5f69a34da6a51-5.png" alt=""/></p><p style="max-width:90%"><code style="margin:0px;padding:0px;">Person是一個函數類型的變量,因此自帶了prototype 屬性,prototype屬性中的constructor又指向Person本身;透過new關鍵字產生的Person類別的實例p1,透過__proto__屬性指向了Person的原型。這裡的__proto__只是為了說明實例p1在內部實現的時候與父類之間存在的關聯(指向父類的原型),在實際操作過程中實例可以直接通過.取得父類別原型中的屬性,從而實現了繼承的功能。

3. 原型鏈

清楚了prototype__proto__的概念與關係之後我們會對「Js中一切皆為物件」這句話有更加深刻的理解。進而我們會想到,既然__proto__是(幾乎)所有物件都內建的屬性,而且指向父類別的原型,那是不是意味著我們可以「逆流而上」一直找到源頭呢?我們來看下面的範例:

<br/>

<br/>

1

## 2

3

4

5

6

7

8

#9

10

##11

12

13

14

15

#16

17

<br/>

// 節點

var#Obj = function##(){}; 

var o = #newObj(); 

o.__proto__ === Obj.prototype;  //=>真的 ######

o.__proto__.constructor === Obj; //=> true

 

##Obj.__proto__ === Function.prototype; //=> true 

Obj.__proto__.constructor === 函數; //=> true## 

#Function.__proto__ === Function.prototype; 

//=> true 

Object.__proto__ === Object.prototype;     

//=>錯誤的 ######<p class="line number12 index11 alt1" style="margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-size:12px;min-height:auto;white-space:nowrap;"><code class="javascript plain" style="margin:0px;padding:0px;background:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-family:Consolas, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, Courier, monospace;min-height:auto;color:rgb(0,0,0);">Object.__proto__ === Function.prototype;   //=> true

 

##Function.__proto__.constructor === Function;//=> true

Function.__proto__.__proto__;               //=> {} 

Function.__proto__.__proto__ === o.__proto__.__proto__; //=>真的 ######

o.__proto__.__proto__.__proto__ === null;   //=>真的##########<p style="margin:10px auto;color:rgb(51,51,51);font-family:Verdana, Arial, Helvetica, sans-serif;font-size:14px;background-color:rgb(255,255,255);"><img src="https://img.php.cn/upload/article/000/054/025/49ab92ca686055e31fa5f69a34da6a51-6.jpg" alt=""/></p><p style="max-width:90%">從上面的範例和圖解可以看出,<code style="margin:0px;padding:0px;">prototype物件也有__proto__屬性,向上回溯一直到null

new關鍵字的作用是完成上圖所示實例與父類別原型之間關係的串接,並建立一個新的物件;instanceof關鍵字的作用也可以從上圖看出,其實就是判斷__proto__(以及__proto__.__proto__...)所指向是否父類別的原型:

<br/>

<br/>

#1

2

3

4

5

6

7

8

9

10

<br/>

#var Obj = 函數(){}; 

#varo = newObj();

 

實例 Obj; //=> true 

instanceofObject; //=> true 

instanceofFunction; //=>錯誤的#########<p class="line number8 index7 alt1" style="margin:0px;padding:0px 1em;background-image:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-size:12px;min-height:auto;white-space:nowrap;"><code class="javascript plain" style="margin:0px;padding:0px;background:none;border:0px;float:none;line-height:1.8em;vertical-align:baseline;font-family:Consolas, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, Courier, monospace;min-height:auto;color:rgb(0,0,0);">o.__proto__ === Obj.prototype; //=> true 

o.__proto__.__proto__ === Object.prototype; //=> true 

o.__proto__.__proto__ === 函數;  //=>錯誤的##########<p style="margin:10px auto;"> </p><p style="margin:10px auto;"> </p><p style="margin:10px auto;"> </p><h1 class="postTitle" style="margin-top:10px;margin-bottom:20px;padding:0px;font-weight:400;line-height:1.8;color:rgb(51,51,51);">JS物件導向之原型鏈</h1><p class="clear" style="clear:both;margin:0px;padding:0px;background:none;border:0px;float:none;line-height:1.1em;vertical-align:baseline;font-family:Consolas, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, Courier, monospace;font-size:12px;min-height:auto;"> </p><p class="postBody" style="margin:0px;padding:0px;background:none;border:0px;float:none;line-height:1.1em;vertical-align:baseline;font-family:Consolas, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, Courier, monospace;font-size:12px;min-height:auto;">&lt;br/&gt;</p><p class="cnblogs-markdown" style="margin-bottom:20px;line-height:1.8;margin-top:0px;margin-right:0px;margin-left:0px;padding:0px;background:none;border:0px;float:none;vertical-align:baseline;font-size:12px;min-height:auto;">&lt;br/&gt;</p><h1 style="margin-top:10px;margin-bottom:10px;padding:0px;line-height:1.5;"></h1><h1 style="margin-top:10px;margin-bottom:10px;padding:0px;line-height:1.5;"></h1><ol style="margin-bottom:1em;margin-left:40px;" class=" list-paddingleft-2"><li><p></p></li><li><p></p></li><li><p><span style="margin:0px;padding:0px;"></span></p>##JS 物件導向之原型鏈</li><li>物件的原型鏈<p></p></li><li>只要是物件就有原型<p></p></li> <li>原型也是物件<p></p></li></ol>只要是物件就有原型, 並且原型也是物件, 因此只要定義了一個物件, 那麼就可以找到他的原型, 如此反覆, 就可以構成一個物件的序列, 這個結構就被成為<h2 style="margin-top:20px;margin-bottom:20px;padding:0px;font-size:21px;line-height:1.5;">原型鏈</h2><ol style="margin-bottom:1em;margin-left:40px;" class=" list-paddingleft-2"><li><p><span style="margin:0px;padding:0px;">#原型鏈到哪裡是一個頭?</span></p></li><li>一個預設的原型鏈結構是什麼樣子的?<p></p></li></ol>原型鏈結構對已知語法結構有什麼修正?<h3 style="margin-top:10px;margin-bottom:10px;padding:0px;font-size:16px;line-height:1.5;"></h3><ol style="margin-bottom:1em;margin-left:40px;" class=" list-paddingleft-2">##原型鏈的結構<li><p></p></li>原型鏈繼承就是利用就是修改<li>原型鏈結構<p>( 增加、刪除、修改節點中的成員), 從而讓實例物件可以使用整個原型鏈中的所有成員( 屬性與方法)</p></li><li><p>使用原型鏈繼承必須滿足屬性搜尋原則</p></li><li><p>屬性搜尋原則</p></li><li><p>所謂的屬性搜尋原則, 就是物件在存取屬性與方法的時候, 首先在目前物件中尋找</p></li><li><p>如果目前物件中儲存在屬性或方法, 停止尋找, 直接使用該屬性與方法</p></li><li><p>如果物件沒有改成員, 那麼再其原型物件中尋找</p></li></ol><h1 style="margin-top:10px;margin-bottom:10px;padding:0px;line-height:1.5;">如果原型物件含有該成員, 那麼停止查找, 直接使用</h1><ol style="margin-bottom:1em;margin-left:40px;" class=" list-paddingleft-2"><li><p style="margin:10px auto;">如果原型還沒有, 就到原型的原型中查找&lt;br/&gt;<code style="margin:1px 5px;line-height:1.8;vertical-align:middle;padding:0px 5px;background:rgb(245,245,245) none;border:1px solid rgb(204,204,204);float:none;text-align:left;font-family:&#39;Courier New&#39;, sans-serif;min-height:auto;white-space:nowrap;"><br/>如此往復,直到直到Object.prototype 還沒有, 那麼就回傳undefind.

  • 如果是呼叫方法就包錯, 該xxxx 不是一個函數

    <br/>

    原型鏈結構圖
  • <br/>建構函數物件原型鏈結構圖

    function Person (){}; var p = new Person();
  • <br/>#{} 物件原型鏈結構圖

  • #[] 陣列原型鏈結構圖
  • ############Object.prototype### 對應的建構子##################p 對應的建構函數############p -> pTag.prototype( 就是o ) -> Object.prototype -> null####
  • var o = {
        appendTo: function ( dom ) {
        }
    };
    function pTag() {}
    pTag.prototype = o;
    
    var p = new pTag();
    登入後複製

    函数的构造函数 Function

    在 js 中 使用 Function 可以实例化函数对象. 也就是说在 js 中函数与普通对象一样, 也是一个对象类型( 非常特殊 )

    1. 函数是对象, 就可以使用对象的动态特性

    2. 函数是对象, 就有构造函数创建函数

    3. 函数是函数, 可以创建其他对象(函数的构造函数也是函数)

    4. 函数是唯一可以限定变量作用域的结构

    函数是 Function 的实例

    new Function( arg0, arg1, arg2, ..., argN, body );
    登入後複製
    1. Function 中的参数全部是字符串

    2. 该构造函数的作用是将 参数链接起来组成函数

    • 如果参数只有一个, 那么表示函数体

    • 如果参数有多个, 那么最后一个参数表示新函数体, 前面的所有参数表示新函数的参数

    • 如果没有参数, 表示创建一个空函数

    创建一个打印一句话的函数

        // 传统的
        function foo () {
            console.log( &#39;你好&#39; );
        }
        // Function
        var func = new Function( &#39;console.log( "你好" );&#39; );
        // 功能上, 这里 foo 与 func 等价
    登入後複製

    创建一个空函数

        // 传统
        function foo () {}
        // Function
        var func = new Function();
    登入後複製

    传入函数内一个数字, 打印该数字

        // 传统
        function foo ( num ) {
            console.log( num );
        }
        // Function
        var func = new Function ( "num" ,"console.log( num );" );
        func();
    登入後複製

    利用 Function 创建一个函数, 要求传入两个数字, 打印其和

        var func = new Function( &#39;num1&#39;, &#39;num2&#39;, &#39;console.log( num1 + num2 );&#39; );
    登入後複製

    练习: 利用 Function 创建一个函数, 要求允许函数调用时传入任意个数参数, 并且函数返回这些数字中最大的数字.<br/>练习: 利用 Function 创建一个求三个数中最大数的函数.

        // 传统
        function foo ( a, b, c ) {
            var res = a > b ? a : b;
            res = res > c ? res : c;
            return res;
        }
        // Function
        var func = new Function( &#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;var res = a > b ? a : b;res = res > c ? res : c;return res;&#39; )
    登入後複製

    解决代码太长的办法:

    1. 利用 加法 连接字符串

      var func = new Function( &#39;a&#39;, &#39;b&#39;, &#39;c&#39;,
              &#39;var res = a > b ? a : b;&#39; +
              &#39;res = res > c ? res : c;&#39; +
              &#39;return res;&#39; );
      登入後複製
    2. 利用字符串特性( 刚学 )

      function foo ( a, b, c ) {
          var res = a > b ? a : b;
          res = res > c ? res : c;
          return res;
      }
      var func = new Function( &#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;return foo( a, b, c );&#39; );
      登入後複製
    3. ES6 的语法( 少浏览器实现 )

      • 使用 键盘左上角的 左单引号 表示可换行字符串的界定符

    4. (最终)利用 DOM 的特性完成该方法

    arguments 对象

    arguments 是一个伪数组对象. 它表示在函数调用的过程中传入的所有参数的集合.<br/>在函数调用过程中没有规定参数的个数与类型, 因此函数调用就具有灵活的特性, 那么为了方便使用,<br/>在 每一个函数调用的过程中, 函数代码体内有一个默认的对象 arguments, 它存储着实际传入的所有参数.

    js 中函数并没有规定必须如何传参

    1. 定义函数的时候不写参数, 一样可以调用时传递参数

    2. 定义的时候写了参数, 调用的时候可以不传参

    3. 定义的时候写了一参数, 调用的时候可以随意的传递多个而参数

    在代码设计中, 如果需要函数带有任意个参数的时候, 一般就不带任何参数, 所有的 参数利用 arguments 来获取.<br/>一般的函数定义语法, 可以写成:

        function foo ( /* ... */ ) {
        }
    登入後複製

    利用 Function 创建一个函数, 要求允许函数调用时传入任意个数参数, 并且函数返回这些数字中最大的数字.

        function foo ( ) {
            // 所有的参数都在 arguments 中. 将其当做数组使用
            // 问题而已转换成在有一个数组中求最大值
            var args = arguments;
            var max = args[ 0 ];
            for ( var i = 1; i < args.length; i++ ) {
                if ( max < args[ i ] ) {
                    max = args[ i ];
                }
            }
            return max;
        }
    登入後複製

    练习: 利用 Function 写一个函数, 要求传入任意个数字 求和

    函数的原型链结构

    任意的一个函数, 都是相当于 Function 的实例. 类似于 {} 与 new Object() 的关系

        function foo () {};
        // 告诉解释器, 有一个对象叫 foo, 它是一个函数
        // 相当于 new Function() 得到一个 函数对象
    登入後複製
    1. 函数有 __proto__ 属性

    2. 函数的构造函数是 Function

    3. 函数应该继承自 Function.prototype

    4. Fucntion.prototype 继承自 Object.protoype

    5. 构造函数有prototype, 实例对象才有__proto__指向原型, 构造函数的原型才有 constructor 指向构造函数

    intanceof

    array instanceof Array
    判断 构造函数 Array 的原型 是否在 实例对象 array 的原型链存在

    相关推荐:

    关于js原型链的7篇文章推荐

    js原型链继承的几个细节问题

    js原型链原理看图说明_javascript技巧

    以上是JS原型鏈詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    相關標籤:
    來源:php.cn
    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    熱門教學
    更多>
    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板