成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS 進階 (一)作用域深入和面向?qū)ο?

chengtao1633 / 1501人閱讀

摘要:進階第一章作用域深入和面向?qū)ο箢A解釋全局作用域當瀏覽器加載頁面的時候,提供了一個全局代碼執(zhí)行的環(huán)境預解釋變量提升在當前的作用域中,代碼執(zhí)行之前,瀏覽器首先會默認的吧所有帶有和的進行提前聲明或定義理解聲明和定義聲明告訴瀏覽器在全局作用域中有

JS進階 第一章作用域深入和面向?qū)ο?/b> 預解釋

1、全局作用域:當瀏覽器加載HTML頁面的時候,提供了一個全局js代碼執(zhí)行的環(huán)境

2、預解釋(變量提升)

在當前的作用域中,js代碼執(zhí)行之前,瀏覽器首先會默認的吧所有帶有var和function的進行提前聲明或定義

1)理解聲明和定義

var num=12;

聲明(declare) : var num;->告訴瀏覽器在全局作用域中有一個num的變量了

如果一個變量只是聲明但是還沒有賦值,默認值是undefined

定義(defined):num=12->給我們的變量進行賦值

2)對于帶var和function關(guān)鍵字的再預解釋的時候操作是不一樣的

var ->在預解釋的時候只是提前聲明不定義

function->在預解釋的時候提前聲明和定義都完成了

3)預解釋只發(fā)生在當前的作用域下,例如:開始只對window下的進行預解釋,只有在函數(shù)執(zhí)行的時候才會對函數(shù)中的進行預解釋

3、JS中內(nèi)存的分類

棧內(nèi)存:用來提供一個供js代碼執(zhí)行的環(huán)境->作用域

堆內(nèi)存:用來存儲引用數(shù)據(jù)類型的值->對象存儲的是屬性名和屬性值,函數(shù)存儲的是代碼字符串。

4、如果區(qū)分私有變量和全局變量?

1)在全局作用域下聲明(預解釋的時候)的變量是全局變量

2)在私有作用域中聲明的變量和函數(shù)的形參都是私有變量

在私有作用域中,我們代碼執(zhí)行的時候遇到了一個變量,首先我們確定它是否是私有變量,如果是私有變量,那么和外面沒有任何的關(guān)系,如果不是使用的,則往當前作用域的上級作用域進行查處,如果上級作用域也沒有則繼續(xù)查找,一直找到window為止...作用域鏈

6、當函數(shù)執(zhí)行的時候(直接目的:讓函數(shù)體中的代碼執(zhí)行),首先會形成一個新的私有作用域,然后按照如下的步驟執(zhí)行:


如果有形參,先給形參賦值

進行私有作用域的預解釋

私有作用域中的代碼從上到下的執(zhí)行

函數(shù)形成一個姓的私有的作用域保護了里面的私有變量不受外界的干擾(外面修改不了私有的,私有的也修改不了外面的),我們管這種機制叫做閉包

7、在全局作用域中,帶var和不帶var的關(guān)系

區(qū)別:帶var的可以進行預解釋,所以在賦值的前面執(zhí)行不會報錯;不帶var的是不能進行預解釋的,在前面執(zhí)行會報錯

8、預解釋是毫無節(jié)操的一種機制

1)預解釋的時候不管你的條件是否成立,都要把帶var的進行提前聲明
if(!("num") in window){
    var num=12;
}
console.log(num);
2)預解釋的時候只預解釋“=”左邊的,右邊的是值,不參與預解釋

匿名函數(shù)之函數(shù)表達式:把函數(shù)定義的部分但當做一個值賦值給我們的變量/元素的某個事件

//window下的預解釋:var fn;
fn();//Uncaught TypeError: fn is not a function
var fn=function(){
    console.log("ok");
}
3)執(zhí)行函數(shù)定義的那個function在全局作用域下不進行預解釋,當前代碼執(zhí)行到這個位置的時候定義和執(zhí)行一起完成了

自執(zhí)行函數(shù):定義和執(zhí)行一起完成了

(function(){})(100);
4)函數(shù)體中return下面的代碼雖然不再執(zhí)行了,但是需要進行預解釋;return后面跟著的都是我們返回的值,所以不進行預解釋
function fn(){
    console.log(num);
    retrun function(){
        
    };
    var num=100;
}
fn();//undefined;
5)在預解釋的時候,如果名字已經(jīng)聲明過了,不需要重新的聲明,但是需要重新的賦值;(在JS中如果變量的名字和函數(shù)的名字重復了,也算沖突了)
var fn=13;
function fn(){
    console.log("ok");
}
console.log(fn);//13
//預解釋的時候先預解釋var fn;function fn{console.log("ok")}
//然后 fn=13->給fn賦值
//最后控制臺輸出的是13
fn();
function fn(){console.log(1)};
fn();
var fn=10;
fn();
function fn(){console.log(2)}
fn();
//window 預解釋:
/*1)聲明+定義 fn=xxxfff000;
    聲明var fn(不需要重新聲明)
    聲明(不重復進行)+定義 fn=xxxfff111;
    預解釋完成后此時的fn變量指向的是堆內(nèi)存地址是xxxfff111
    即:存儲“console.log(2)”代碼字符串的堆內(nèi)存空間
  2)代碼由上到下執(zhí)行
      fn()//2
      fn();//2
      fn=10;
      fn();//Error:fn is not a function
      js代碼出錯,在沒有任何特殊處理的情況下后面的代碼不執(zhí)行
 */

9、如果查找當前作用域的上一級作用域?

看當前函數(shù)是在那個作用域下定義的,那么他的上級作用域就是誰->和函數(shù)在哪執(zhí)行沒有任何關(guān)系

內(nèi)存釋放和作用域銷毀

堆內(nèi)存釋放

對象數(shù)據(jù)類型或者函數(shù)數(shù)據(jù)類型在定義的時候首先都會開辟一個堆內(nèi)存,堆內(nèi)存有一個引用的地址,如果外面有變量等知道這個地址,我們就說這個內(nèi)存被占用了,就不能銷毀

我們?nèi)绻胍褍?nèi)存釋放/銷毀,只需要把所有引用他的變量賦值為null即可,如果當前的堆內(nèi)存沒有任何東西被占用,那么瀏覽器會在空閑的時候把他銷毀

var obj1={name:"candy"}
var obj2=obj1;
obj1=null;
obj2=null;

棧內(nèi)存的銷毀

1)全局作用域只有當前頁面關(guān)閉的時候全局作用域才會被銷毀

2)私有作用域(只有函數(shù)執(zhí)行才會產(chǎn)生私有作用域)

一般情況下,函數(shù)執(zhí)行會形成一個新的私有的作用域,當私有作用域中的代碼執(zhí)行完成后,我們當前作用域都會主動的進行釋放和銷毀

但是還是存在特殊情況的:

當前私有作用域中的部分被作用域以外的東西占用了,那么當前的這個作用域就不能銷毀了

函數(shù)執(zhí)行返回了一個引用數(shù)據(jù)類型的值,并且在函數(shù)的外面被一個其他的東西接收了,這種情況下一般形成的私有作用域都不會銷毀

在一個私有作用域中給DOM元素的事件綁定方法,一般情況下我們的使用作用域都不能銷毀

下述情況不能立即銷毀:fn返回的函數(shù)沒有被其他的東西占用,但是還需要執(zhí)行一次,所以暫時不銷毀,當返回的值執(zhí)行完成后,瀏覽器會在空閑的時候把他銷毀

function fn(){
    var num=100;
    return function(){
        
    }
}
var f=fn();//fn執(zhí)行形成的這個私有作用域就不能被銷毀
var oDiv=document.getElementById("div1");
~function(){
    oDiv.onclick=function(){
        
    }
}()//當前自執(zhí)行函數(shù)形成的這個使用作用域也不能銷毀
function fn(){
    var num=100;
    return function(){
        
    }
}
fn()();//首先執(zhí)行fn,返回一個小函數(shù)對應的內(nèi)存地址,然后緊接著讓返回的小函數(shù)執(zhí)行
this
我們在js中主要研究的都是函數(shù)中的this

JS中this代碼的是當前行為執(zhí)行的主體;JS中的context代表的是當前行為執(zhí)行的環(huán)境(區(qū)域)

this是誰和函數(shù)在哪定義的和在哪執(zhí)行的都沒有任何的關(guān)系*

如何區(qū)分this?

函數(shù)執(zhí)行,首先看函數(shù)名前面是否有“.”,有的話 “.”前面是誰this就是誰,沒有的話就是window

自執(zhí)行函數(shù)中的this永遠是window

給元素的某一個事件綁定方法,當事件觸發(fā)的時候,執(zhí)行對應的方法,方法中的this是當前的元素

單例模式

1、對象數(shù)據(jù)類型的作用:把描述同一個實物(同一個對象)的屬性和方法放在一個內(nèi)存空間下,起到了分組的作用,這樣不同事物之前的屬性名即使相同也不會發(fā)生沖突->我們把這種分組編寫代碼的模式叫做 單例模式

//在單例模式中我們把person1或者person2也叫做“命名空間”
var person1={
    name:"candy",
    age:28
}
var person2={
    name:"andy",
    age:30
}

2、單例模式是一種項目開發(fā)中經(jīng)常使用的模式,因為項目中我們可以使用單例模式來進行我們的“模塊化開發(fā)”

模塊化開發(fā) :對于一個相對來說比較大的項目,需要多個人協(xié)作開發(fā)的,我們一般情況下會根據(jù)當前項目的需求劃分成幾個功能版塊,每個人負責一部分,同時開發(fā),最后把每個人的代碼合并

//公共模塊
var utils={
    select:function(){
        
    }
}
//頁卡模塊中的change->實現(xiàn)選項卡切換
var tabRender={
    change:function(){
        utils.select();//在自己的命名空間下調(diào)用其他的命名空間的方法
    }
}
//搜索模塊change->搜索內(nèi)容變化處理
var serchRender={
    change:function(){
        
    },
    clickEven:function(){
        this.change();//在自己的命名空間下調(diào)用其他的命名空間的方法
    }
    
}
工廠模式

1、單例模式雖然解決了分組的作用,但是不能 實現(xiàn)批量生產(chǎn),屬于手工作業(yè)模式,為了應對這種情況就催生了“工廠模式”;

工廠模式:把實現(xiàn)同一件事情的相同代碼放到一個函數(shù)中,以后如果想再實現(xiàn)這個功能,不需要重新的編寫這些代碼了,只需要執(zhí)行當前的函數(shù)即可;我們把這種形式又稱為 函數(shù)的封裝

作用:低耦合高內(nèi)聚->減少頁面中的冗余代碼,提高代碼的重復利用率

function createJsPerson(name,age){
    var obj={};
    obj.name=name;
    obj.age=age;
    obj.writeJs=function(){
        console.log("my name is "+this.name+",i can write js!");
    }
    return obj;
}
var p1=createJsPerson("andy",30);
p1.writeJS();
var p2=createJsPerson("candy",28);
p2.writeJS();

JS中不存在重載

JS是一門輕量級的腳本”編程語言“(HTML+CSS不屬于編程語言,屬于標記語言)

所有的編程語言都是面向?qū)ο箝_發(fā)的->類的繼承、封裝、多態(tài)

繼承:子類繼承父類中的屬性和方法

多態(tài):當前方法的多種形態(tài)->后臺語言中:多態(tài)包含重載和重寫

//后臺中的重載
public void sum(int num1,int num2){
    
}
public void sum(String num1,int num2){
    
}
function sum(num1,num2){
    
}
function sum(num1){
    
}
//js中不存在重載,方法名一樣的話,后面的會把前面的覆蓋掉,最后只保留一個
JS中有一個操作類似重載的方法但是不是重載:我們可以根據(jù)傳遞參數(shù)的不一樣,實現(xiàn)不同的功能

重寫:子類重寫父類的方法

function sum(num){
    if(typeOf num==="undefined"){
        return 0;
    }
    return num();
}
sum(100);
sum();
構(gòu)造函數(shù)模式
//構(gòu)造函數(shù)模式的目的就是為了創(chuàng)建一個自定義類,并且創(chuàng)建這個類的實例
function CreateJsPerson(name,age){
    //瀏覽器默認創(chuàng)建的對象就是我們的實例p1->this
    this.name=name;
    this.age=age;
    this.writeJs=function(){
        console.log("my name is "+this.name+",i can write js");
    }
    //瀏覽器再把創(chuàng)建的實例默認的進行返回
}
var p1=new CreateJsPerson("candy",28);
p1.writeJs();

var res=CreateJsPerson("andy",30);
console.log(res);
/*
這樣寫不是構(gòu)造函數(shù)執(zhí)行而是普通的函數(shù)執(zhí)行
由于沒有寫return 所以 res=undefined
并且CreateJsPerson這個方法中的this是window
*/
var p2=new CreateJsPerson("candice",29);
p2.writeJs();

1、構(gòu)造函數(shù)模式和工廠模式的區(qū)別?

1)執(zhí)行的時候

普通函數(shù)執(zhí)行->createJsPerson();

構(gòu)造函數(shù)模式->new CreateJsPerson() 通過new執(zhí)行后,我們的CreateJsPerson就是一個類了;而函數(shù)執(zhí)行的返回值(p1)就是CreateJsPerson這個類的一個實例

2)在函數(shù)代碼執(zhí)行的時候

相同點:都是形成一個私有的作用域,然后 形參賦值->預解釋->代碼從上到下執(zhí)行(類和普通函數(shù)一樣,它也有普通函數(shù)的一面)

不同點:在代碼執(zhí)行之前,構(gòu)造函數(shù)模式不用自己在手動的創(chuàng)建對象了,瀏覽器會默認的創(chuàng)建一個對象數(shù)據(jù)類型的值(這個對象其實就是我們當前類的一個實例);接下來代碼從上到下執(zhí)行,以當前的實例為執(zhí)行的主體(this代表的就是當前的實例),然后分別把屬性名和屬性值賦值給當前的實例,最后瀏覽器會默認的把創(chuàng)建的實例返回

2、構(gòu)造函數(shù)解析

1)JS中所有的類都是函數(shù)數(shù)據(jù)類型的,它通過new執(zhí)行變成了一個類,但是它本身也是一個普通的函數(shù);JS中所有的實例都是對象數(shù)據(jù)類型

2)在構(gòu)造函數(shù)模式中,類中(函數(shù)體中)出現(xiàn)的this.xxx=xxx中的this是當前類的一個實例

3)p1和p2都是CreateJsPerson這個類的實例,所以都擁有writeJs這個方法,但是不同實例之間的方法是不一樣的,在類中給實例增加的屬性(this.xxx=xxx)屬于當前實例的私有屬性,實例和實例之間是多帶帶的個體,所以私有的屬性之間是不相等的

console.log(p1.writeJs===p2.writeJs);//false

3、構(gòu)造函數(shù)相關(guān)知識點

function Fn(){
    this.x=100;
    this.getX=function(){
        console.log(this.x);
    }
}
var f1=new Fn;
f1.getX();//->方法中的this是f1->100
var ss=f1.getX;
ss();//方法中的this是window->undefined

在構(gòu)造函數(shù)模式中的new Fn執(zhí)行,如果Fn不需要傳遞參數(shù)的話,后面的小括號可以省略

this的問題:在類中出現(xiàn)的this.xxx=xxx中的this都是當前類的實例,而某一個屬性值(方法),方法中的this需要看方法執(zhí)行的時候,前面是否有“.”才能知道this是誰

function Fn(){
    var num=10;
    this.x=100;
    this.getX=function(){
        console.log(this.x);
    }
}
var f1=new Fn;
console.log(f1.num);//=>undefined

類有普通函數(shù)的一面,當函數(shù)執(zhí)行的時候,var num 其實只是當前形成的私有作用域中的私有變量而已,它和我們f1這個實例沒有任何的關(guān)系,只有this.xxx=xxx才相當于給f1這個實例增加私有的屬性和方法,才和我們的f1有關(guān)系

function Fn(){
    this.x=100;
    this.getX=function(){
        console.log(this.x);
    }
    return {name:"candy"};
}
var f1=new Fn;
console.log(f1);//{name:"candy"}

在構(gòu)造函數(shù)模式中,瀏覽器會默認的把我們的實例返回(返回的是一個對象數(shù)據(jù)類型的值);如果我們自己手動寫了return返回:

返回的是一個基本數(shù)據(jù)類型的值,當前的實例是不變的,例如:return 100;我們的f1還是當前fn類的實例

返回的是一個引用數(shù)據(jù)類型的值,當前的實例會被自己返回的值給替換掉,例如:return {name:"candy"},f1就不再是fn的實例了,而是對象{name:"candy"}

function Fn(){
    this.x=100;
    this.getX=function(){
        console.log(this.x);
    }
}
var f1=new Fn;
console.log(f1 instanceof Fn);//true
console.log(f1 instanceof Array);//false
console.log(f1 instanceof Object);//true
//因為所有的實例都是對象數(shù)據(jù)類型的,而每一個對象數(shù)據(jù)類型都是Object這個內(nèi)置類的一個實例,所以f1也是它的一個實例

檢測某一個實例是否屬于這個類->instanceof

function Fn(){
    this.x=100;
    this.getX=function(){
        console.log(this.x);
    }
}
var f1=new Fn;
var f1=new Fn;
console.log(f1.getX===f2.getX);//false
console.log("getX" in f1);//true
console.log(f1.hasOwnProperty("getX"));//ture

f1和f2都是Fn這個類的一個實例,都擁有x和getX這兩個屬性,但是這兩個屬性是各自的私有屬性

in:檢測某一個屬性是否屬于這個對象(attr in object),不管是私有的屬性還是公有的屬性,只要存在,用in來檢測都是true

hasOwnProperty:用來檢測某個屬性是否為這個對象的私有屬性,這個方法只能檢測私有的屬性

檢測某一個屬性是否為該對象的“公有屬性”->hasPubProperty

function hasPubProperty(obj,attr){
    return (attr in obj) && !obj.hasOwnProperty(attr);
}

原型鏈模式
實例識別:構(gòu)造函數(shù)模式中擁有類和實例的概念,并且實例和實例之間是相互獨立開的

基于構(gòu)造函數(shù)模式的原型模式解決了 方法或者屬性公有的問題->把實例之間相同的屬性和方法提取成公有的屬性和方法(想讓誰公有就把他放在當前類的原型上xxx.prototype即可)

原型鏈模式的三句話

每一個函數(shù)數(shù)據(jù)類型(普通函數(shù),類)都有一個天生自帶的屬性:prototype(原型),并且這個屬性是一個對象數(shù)據(jù)類型的值

并且在prototype上瀏覽器天生給他加了一個屬性constrctor(構(gòu)造函數(shù)),屬性值是當前函數(shù)(類)本身

每一個對象數(shù)據(jù)類型(普通對象,實例,prototype...)也天生自帶一個屬性:(__proto__),這個屬性值是當前實例所屬類的原型(prototype)

function Fn(){
    this.x=100;
    this.sum=function(){}
}
Fn.prototype.getX=function(){
    console.log(this.x);
}
Fn.prototype.sum=function(){
    
}
var f1=new Fn;
var f2=new Fn;
console.log(Fn.prototype.constructor===Fn);//true

Object是JS中所有對象數(shù)據(jù)類型的基類(最頂層的類)

f1 instanceof Object->true 因為f1通過__proto__可以向上級查找,不管有多少級,最后總能找到Object

在Object.prototype上沒有__proto__這個屬性

原型鏈模式
f1.hasOwnProperty("x");//hasOwnProperty是f1的一個屬性

但是我們發(fā)現(xiàn)在f1的私有屬性上沒有這個方法,那如何處理的呢?

通過對象名.屬性名的方式獲取屬性值的時候,首先在對象的私有屬性上進行查找,如果私有中存在這個屬性,則獲取的是私有的屬性值;如果私有的沒有,則通過__proto__找到所屬類的原型(類的原型上定義的屬性和方法都是當前實例的公有的屬性和方法),原型上存在的話,獲取的是公有的屬性值如果原型上也沒有,則繼續(xù)通過原型上的__proto__繼續(xù)向上查找,一直找到Object.prototype為止

——>這種查找的機制就是我們的原型鏈模式

**在IE瀏覽器中,我們的原型模式也是同樣的原理,但是IE瀏覽器怕你通過__proto__把公有的修改,禁止我們使__proto__

在原型模式中,this常用的有兩種情況

在類中this.xxx=xxx;this指的是當前類的實例

某一個方法中他的this,看執(zhí)行的時候“.”前面是誰,this就是誰

需要先確定this的指向(this是誰)

需要把this替換成對應的代碼

按照原型鏈查找機制,一步步的查找結(jié)果

function Fn(){
    this.x=100;
    this.y=200;
    this.getY=function(){
        console.log(this.y);
    }
}
Fn.prototype={
    constructor:fn,
    y:300,
    getX:function(){
        console.log(this.x);
    },
    getY:function(){
        console.log(this.y)
    }
}
var f=new Fn();
f.getX();//console.log(f.x)->100
f.__proto__.getX();//this是f.__proto__->console.log(f.__proto__.x)->undefined
Fn.prototype.getX();//undefied
f.getY();//200
f.__proto__.getY();//300
//在內(nèi)置類的原型上擴展我們的方法:
Array.prototype.myUnique=function myUnique(){
    //this->ary
    var obj={};
    for(var i=0;i[12,13,23,24]
//鏈式寫法:執(zhí)行完成數(shù)組的一個方法可以緊接著執(zhí)行下一個方法
//因為sort是Array.prototype上的公有方法,而數(shù)組ary是Array這個類的一個實例,所以ary可以使用sort方法->數(shù)組才能是用我們Array原型上的屬性和方法
批量設置公有屬性
//1、起一個別名
function Fn(){
    this.x=100;
}
var pro=Fn.prototype;//把原來原型執(zhí)行的地址賦值給我們的pro,現(xiàn)在他們操作的是同一個內(nèi)存空間
pro.getX=function(){};
pro.getY=function(){};
pro.getZ=function(){};
var f1=new Fn;
//2、重構(gòu)原型對象的方式->自己新開辟一個堆內(nèi)存,存儲我們公有的屬性和方法,把瀏覽器原來給的Fn.prototype開辟的那個替換掉
function Fn(){
    this.x=100;
}
Fn.prototype={
    constructor:Fn,
    a:function(){},
    b:function(){}
}
var f=new Fn;
f.a();
f.b();
//A、只有瀏覽器天生給的Fn.prototype開辟的堆內(nèi)存里面才有constructor,而我們自己開辟的這個堆內(nèi)存沒有這個屬性,這樣constructor指向就不是Fn而是Object了 為了和要來保持一致,我們需要手動的增加constructor的指向
//B.給內(nèi)之類增加公有的屬性 例:Array.prototype.unique=function(){}
    //如果我們用上面代碼中的方法修改內(nèi)之類的話,瀏覽器會屏蔽掉,但是我們可以一個個的修改內(nèi)置的方法,當我們通過這種方式增加方法,如果方法名和原來內(nèi)置的重復了,會把內(nèi)置的修改掉->所以在以后內(nèi)之類的原型上增加方法,命名都需要加特殊的前綴
//for in循環(huán)在遍歷的時候,默認的話可以把自己的私有的和他所屬類原型上擴展的屬性和方法都可以遍歷到,但是一般情況下,我們遍歷一個對象只需要遍歷私有的即可,我們可以使用以下判斷進行處理
var obj={name:"candy",age:28}
for(var key in obj){
    if(obj.prototypeIsEnumberable(key)){
           console.log(key);
    }
    if(obj.hasOwnProperty(key)){
        console.log(key)
    }
}
//Object.create(proObj)創(chuàng)建一個新的對象,但是還要吧proObj作為這個對象的原型 在IE6~8不兼容(ECMAScript5)
/***
var obj={
    getX:function(){}
}
var obj2=Object.create(obj);
obj2.getX();
obj.getY=function(){
    console.log(2);
}
obj2.getY();
***/
var obj={
    getX:function(){
        console.log(1);
    }
};
function object(o){
    function Fn(){}
    Fn.prototype=o;
    return new Fn;
}
var newObj=object(obj);
newObj.getX();
常用的六種繼承模式
原型繼承

原型繼承是我們JS中最常用的一種繼承方式

function A(){
    this.x=100;
}
A.prototype.getX=function(){
    console.log(this.x);
}
function B(){
    this.y=200;
    this.x=200;
}
B.prototype=new A;
B.prototype.constructor=B;
var n=new B;
n.getX();//200;

原型繼承的特點:它是把父類中的私有的+公有的都繼承到子類原型上(子類公有的)

核心:原型鏈繼承并不是把父類中的屬性和方法克隆一份一模一樣的給B,而是讓B和A之間增加了原型鏈的鏈接,以后B的實例n想要用A中的getX方法,需要一級一級的向上查找

call繼承

call繼承:把父類私有的屬性和方法 克隆一份一模一樣的作為子類私有的屬性

function A(){
    this.x=100;
}
A.prototype.getX=function(){
    console.log(this.x);
}
function B(){
    A.call(this);//A.call(n) 把A執(zhí)行讓A中的this變?yōu)閚
}
var n=new B;
console.log(n.x);//100
 n.getX();//Uncaught TypeError: n.getX is not a function
冒充對象繼承

冒充對象繼承:把父類私有的+公有的 克隆一份一模一樣的給子類私有的

function A(){
    this.x=100;
}
A.prototype.getX=function(){
    console.log(this.x);
}
function B(){
    var temp=new A;
    for(var key in temp){
        this[key]=temp[key];
    }
    temp=null;
}
var n=new B;
n.getX();
寄生組合式繼承
function A(){
    this.x=100;
}
A.prototype.getX=function(){
    console.log(this.x);
}
B.prototype=objectCreate(A.prototype);
B.prototype.constructor=B;
var n=new B;
n.getx();
function objectCreate(o){
    function Fn(){
    }
    Fn.prototype=o;
    return new Fn;
}
混合模式繼承

混合模式繼承:原型繼承+call繼承

function A(){
    this.x=100;
}
A.prototype.getX=function(){
    console.log(this.x);
}
function B(){
    A.call(this);//n.x=100
}
B.prototype=new A;//B.prototype: x=100 getX...
B.prototype.constructor=B;
中間類繼承法
function avgFn(){
    Array.prototype.sort.call(arguments,function(a,b){
        return a-b;
    })
    Array.prototype.pop.call(arguments);
    Array.prototype.shift.call(arguments);
    return (eval(Array.prototype.join.call(arguments,"+"))
            /arguments.length).toFixed(2)
}
console.log(avgFn(10,20,30,10,30,40,40))
function avgFn(){
    arguments.__proto__=Array.prototype;
    arguments.sort(function(a,b){
        return a-b;
    })
    arguments.pop();
    arguments.shift();
    return (eval(arguments.join("+"))/arguments.length).toFixed(2);
}
console.log(avgFn(10,20,30,10,30,40,40));
思考題

1.在數(shù)組的原型上有一個方法叫做slice,我們要求大家自己回去后實現(xiàn)一個方法mySlice,要求和原來的slice功能一模一樣

Array.prototype.mySlice=function mySlice(){
    var ary=[];
     var num=0,
        start=parseInt(Number(arguments[0])),
        end=parseInt(Number(arguments[1]));
     if(end===undefined||end>this.length){
            end=this.length;
       }else if(!start){
            start=0;
       }
      start>=0?null:start+=this.length;
      end>=0?null:end+=this.length;
       for(var i=start;i

2、實現(xiàn)一個需求(5).plus(10).reduce(2) =>5+10-2

Number.prototype.plus=function plus(num){
    return this.valueOf()+num;
}
Number.prototype.reduce=function reduce(num){
    return this.valueOf()-num;
}
var m=(5).plus(10).reduce(2);
console.log(m);

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/96272.html

相關(guān)文章

  • javasscript - 收藏集 - 掘金

    摘要:跨域請求詳解從繁至簡前端掘金什么是為什么要用是的一種使用模式,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題。異步編程入門道典型的面試題前端掘金在界中,開發(fā)人員的需求量一直居高不下。 jsonp 跨域請求詳解——從繁至簡 - 前端 - 掘金什么是jsonp?為什么要用jsonp?JSONP(JSON with Padding)是JSON的一種使用模式,可用于解決主流瀏覽器的跨域數(shù)據(jù)訪問的問題...

    Rango 評論0 收藏0
  • 進階2-1期】深入淺出圖解作用閉包

    摘要:本期推薦文章從作用域鏈談閉包,由于微信不能訪問外鏈,點擊閱讀原文就可以啦。推薦理由這是一篇譯文,深入淺出圖解作用域鏈,一步步深入介紹閉包。作用域鏈的頂端是全局對象,在全局環(huán)境中定義的變量就會綁定到全局對象中。 (關(guān)注福利,關(guān)注本公眾號回復[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實戰(zhàn)、面試指導) 本周開始前端進階的第二期,本周的主題是作用域閉包,今天是第6天。 本...

    levius 評論0 收藏0
  • 【連載】前端個人文章整理-從基礎(chǔ)到入門

    摘要:個人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個目錄,方便更多的小伙伴去學習。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個人前端文章整理 從最開始萌生寫文章的想法,到著手...

    madthumb 評論0 收藏0
  • JS程序

    摘要:設計模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設計模式必須要先搞懂面向?qū)ο缶幊?,否則只會讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學習總結(jié)。知識只有分享才有存在的意義。 是時候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...

    melody_lql 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<