国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

深入理解javascript原型和閉包

_ang / 2197人閱讀

摘要:情況構(gòu)造函數(shù)所謂構(gòu)造函數(shù)就是用來對(duì)象的函數(shù)。另外注意,構(gòu)造函數(shù)的函數(shù)名第一個(gè)字母大寫規(guī)則約定。閉包但是你只需要知道應(yīng)用的兩種情況即可函數(shù)作為返回值,函數(shù)作為參數(shù)傳遞。如上代碼,函數(shù)作為返回值,賦值給變量。這就是需要理解閉包的核心內(nèi)容。

原文鏈接http://www.cnblogs.com/wangfupeng1988/p/3977924.html

對(duì)象是屬性的集合。
function show(x) {
    
                console.log(typeof(x));    // undefined
                console.log(typeof(10));   // number
                console.log(typeof("abc")); // string
                console.log(typeof(true));  // boolean
    
                console.log(typeof(function () { }));  //function
    
                console.log(typeof([1, "a", true]));  //object
                console.log(typeof ({ a: 10, b: 20 }));  //object
                console.log(typeof (null));  //object
                console.log(typeof (new Number(10)));  //object
            }
show();

以上代碼列出了typeof輸出的集中類型標(biāo)識(shí),其中上面的四種(undefined, number, string, boolean)屬于簡單的值類型,不是對(duì)象。剩下的幾種情況——函數(shù)、數(shù)組、對(duì)象、null、new Number(10)都是對(duì)象。他們都是引用類型。
判斷一個(gè)變量是不是對(duì)象非常簡單。值類型的類型判斷用typeof,引用類型的類型判斷用instanceof。

對(duì)象都是通過函數(shù)來創(chuàng)建的

函數(shù)就是對(duì)象的一種,因?yàn)橥ㄟ^instanceof函數(shù)可以判斷。

var fn = function () { };
console.log(fn instanceof Object);  // true
var obj = { a: 10, b: 20 };
var arr = [5, "x", true];

這是種語法糖,是一種快捷方式。真實(shí)代碼是:

//var obj = { a: 10, b: 20 };
        //var arr = [5, "x", true];

        var obj = new Object();
        obj.a = 10;
        obj.b = 20;

        var arr = new Array();
        arr[0] = 5;
        arr[1] = "x";
        arr[2] = true;

而其中的 Object 和 Array 都是函數(shù)。說明一切對(duì)象都是由函數(shù)創(chuàng)建的。
對(duì)象是函數(shù)創(chuàng)建的,而函數(shù)卻又是一種對(duì)象

typeof(Array)//"function"
typeof([1,2])//"object",[1,2]其實(shí)是new Array();
typeof(function() {})//"function"
prototype原型

函數(shù)有prototype屬性,對(duì)象有_proto_屬性。
每個(gè)函數(shù)都有一個(gè)屬性叫做prototype。這個(gè)prototype的屬性值是一個(gè)對(duì)象(屬性的集合,再次強(qiáng)調(diào)!),默認(rèn)的只有一個(gè)叫做constructor的屬性,指向這個(gè)函數(shù)本身。
如上圖,SuperType是是一個(gè)函數(shù),右側(cè)的方框就是它的原型。

接著往下說,你也可以在自己自定義的方法的prototype中新增自己的屬性

function Fn() { }
Fn.prototype.name = "王福朋";
Fn.prototype.getYear = function () {
    return 1988;
};

還有一種很容易被混淆的定義函數(shù)方法:

var func = function() {}
func.prototype.name = "prototype test";
func.prototype.protoFunc = function() {console.log("protoFunc")};
func.a = function() {console.log("定義對(duì)象的屬性")}
func.a();//func是個(gè)對(duì)象,func是個(gè)引用。
var funcObject = new func();
console.log(new func(), "new func()");//function() {}
console.log(funcObject, "funcObject");//function() {}
funcObject.name;
funcObject.protoFunc();
funcObject.a();//funcObject.a is not a function(…),

////////////////////
//func是個(gè)對(duì)象,有a這個(gè)屬性,
//funcObject是個(gè)對(duì)象,但是a不是funcObject的屬性。func的所有prototype的屬性就是funcObject的屬性。
function Fn() {};
Fn.prototype.protoFunc = function() {return "aa";console.log("protoFunc")};
Fn.a = function() {}
var fn= new Fn();
fn.protoFunc() //"aa"
fn.a();//FnObject 不是Fn對(duì)象,所以a()方法沒定義。

即,F(xiàn)n是一個(gè)函數(shù),fn對(duì)象是從Fn函數(shù)new出來的,這樣fn對(duì)象就可以調(diào)用Fn.prototype中的屬性。
因?yàn)槊總€(gè)對(duì)象都有一個(gè)隱藏的屬性——“__proto__”,這個(gè)屬性引用了創(chuàng)建這個(gè)對(duì)象的函數(shù)的prototype。即:fn.__proto__ === Fn.prototype.這里的"__proto__"成為“隱式原型”

繼承(原型鏈)
function Foo() {}
var f1= new Foo();
f1.a = 10
Foo.prototype.a = 100;
Foo.prototype.b = 200;
console.log(f1.a)//10
console.log(f1.b)//200

f1是Foo函數(shù)new出來的對(duì)象,f1.a是f1對(duì)象的基本屬性,f1.b是怎么來的呢?——從Foo.prototype得來,因?yàn)閒1.__proto__指向的是Foo.prototype
訪問一個(gè)對(duì)象的屬性時(shí),先在基本屬性中查找,如果沒有,再沿著__proto__這條鏈向上找,這就是原型鏈。

靈活的原型鏈

如果你要添加內(nèi)置方法的原型屬性,最好做一步判斷,如果該屬性不存在,則添加。如果本來就存在,就沒必要再添加了。

繼承--原型鏈

理解這張圖有以下幾點(diǎn):
1.一切皆對(duì)象,所以每個(gè)對(duì)象都有_proto_屬性,_proto_屬性指向創(chuàng)建該對(duì)象的函數(shù)的prototype。
2.prototype的屬性值是一個(gè)對(duì)象(默認(rèn)的只有一個(gè)叫做constructor的屬性,指向這個(gè)函數(shù)本身)。所以各函數(shù)的prototype也有_proto_屬性。
3.Object函數(shù)的_proto_只想null。
4.var Foo = new Function();則Foo._proto_指向Function.prototype.
5.function Function(){}是有它自己創(chuàng)造的,所有Function._proto_指向Function.prototype.

執(zhí)行上下文

在“準(zhǔn)備工作”中完成了哪些工作:

console.log(a)//a is not defined

console.log(a)//undefined
var a;

console.log(a)//undefined
var a = 10;

console.log(a)//function a() {}函數(shù)聲明
function a() {}

console.log(a)//undefined 函數(shù)表達(dá)式
var a = function(){}

console.log(this)//Window {external: Object, chrome: Object, document: document, lock: Object, SF: Object…} 
//this在任意環(huán)境下都有值

變量、函數(shù)表達(dá)式--變量聲明,默認(rèn)賦值為undefined;

this——賦值

函數(shù)聲明——賦值;
這三種數(shù)據(jù)的準(zhǔn)備情況我們稱之為“執(zhí)行上下文”或者“執(zhí)行上下文環(huán)境”。

給執(zhí)行上下文環(huán)境下一個(gè)通俗的定義——在執(zhí)行代碼之前,把將要用到的所有的變量都事先拿出來,有的直接賦值了,有的先用undefined占個(gè)空。

this

在函數(shù)中this到底取何值,是在函數(shù)真正被調(diào)用執(zhí)行的時(shí)候確定的,函數(shù)定義的時(shí)候確定不了。因?yàn)閠his的取值是執(zhí)行上下文環(huán)境的一部分,每次調(diào)用函數(shù),都會(huì)產(chǎn)生一個(gè)新的執(zhí)行上下文環(huán)境。
情況1:構(gòu)造函數(shù)
所謂構(gòu)造函數(shù)就是用來new對(duì)象的函數(shù)。其實(shí)嚴(yán)格來說,所有的函數(shù)都可以new一個(gè)對(duì)象,但是有些函數(shù)的定義是為了new一個(gè)對(duì)象,而有些函數(shù)則不是。另外注意,構(gòu)造函數(shù)的函數(shù)名第一個(gè)字母大寫(規(guī)則約定)。例如:Object、Array、Function等。

function Foo() {
    this.name = "name";
    this.year = "year";
    console.log(this);
}

var f1 = new Foo();//Foo {name: "name", year: "year"}
Foo();//Window {external: Object, chrome: Object, document: document, lock: Object, SF: Object…}

如果函數(shù)作為構(gòu)造函數(shù)用,那么其中的this就代表它即將new出來的對(duì)象。
如果直接調(diào)用Foo函數(shù),而不是new Foo(),這種情況下this是window。

情況2:函數(shù)作為對(duì)象的一個(gè)屬性

var obj = {
    x:10,
    fn:function(){
     console.log(this);    
     console.log(this.x);
    }
}

var fn1 = obj.fn;
fn1();//Window {external: Object, chrome: Object, document: document, lock: Object, SF: Object…} undefined
obj.fn();//Object {x: 10}  10

fn不僅作為一個(gè)對(duì)象的一個(gè)屬性,而且的確是作為對(duì)象的一個(gè)屬性被調(diào)用。結(jié)果this就是obj對(duì)象。
注意,如果fn函數(shù)不作為obj的一個(gè)屬性被調(diào)用。如上代碼,如果fn函數(shù)被賦值到了另一個(gè)變量中,并沒有作為obj的一個(gè)屬性被調(diào)用,那么this的值就是window,this.x為undefined。

情況3:函數(shù)用call或者apply調(diào)用
當(dāng)一個(gè)函數(shù)被call和apply調(diào)用時(shí),this的值就取傳入的對(duì)象的值。

var obj = {
    x : 1
}

var fn = function() {
    console.log(this);
    console.log(this.x);
}

fn.call(obj);//Object {x: 1} 1

情況4:調(diào)用普通函數(shù)

var obj = {
    x:10,
    fn:function(){
         console.log(this);    //Object {x: 10}
         console.log(this.x);    //10
         function f() {
             console.log(this);    // Window {external: Object, chrome: Object, document: document, lock: Object, SF: Object…}
             console.log(this.x);//undefined
         }
         f();
    }
}

obj.fn();

函數(shù)f雖然是在obj.fn內(nèi)部定義的,但是它仍然是一個(gè)普通的函數(shù),this仍然指向window。

簡介【作用域】

你光知道“javascript沒有塊級(jí)作用域”是完全不夠的,你需要知道的是——javascript除了全局作用域之外,只有函數(shù)可以創(chuàng)建的作用域。
所以,我們?cè)诼暶髯兞繒r(shí),全局代碼要在代碼前端聲明,函數(shù)中要在函數(shù)體一開始就聲明好。除了這兩個(gè)地方,其他地方都不要出現(xiàn)變量聲明。而且建議用“單var”形式。
jQuery源碼的最外層是一個(gè)自動(dòng)執(zhí)行的匿名函數(shù):


為什么要這樣做呢?

原因就是在jQuery源碼中,聲明了大量的變量,這些變量將通過一個(gè)函數(shù)被限制在一個(gè)獨(dú)立的作用域中,而不會(huì)與全局作用域或者其他函數(shù)作用域的同名變量產(chǎn)生沖突。
全世界的開發(fā)者都在用jQuery,如果不這樣做,很可能導(dǎo)致jQuery源碼中的變量與外部javascript代碼中的變量重名,從而產(chǎn)生沖突。

閉包

但是你只需要知道應(yīng)用的兩種情況即可——函數(shù)作為返回值,函數(shù)作為參數(shù)傳遞。

function fn(){
    var max = 10;
    return function bar(x){
        if(x > max) {
            console.log(x);
        }
    };
}

var f1 = fn();
f1(15);//15

如上代碼,bar函數(shù)作為返回值,賦值給f1變量。執(zhí)行f1(15)時(shí),用到了fn作用域下的max變量的值。

第二,函數(shù)作為參數(shù)被傳遞

var max = 10;
fn = function(x){
    if(x > max) {
        console.log(x);
    }
};

(function(f) {
    var max = 100;
    f(15);//15
})(fn);

如上代碼中,fn函數(shù)作為一個(gè)參數(shù)被傳遞進(jìn)入另一個(gè)函數(shù),賦值給f參數(shù)。執(zhí)行f(15)時(shí),max變量的取值是10,而不是100。
自由變量跨作用域取值時(shí),要去創(chuàng)建這個(gè)函數(shù)的作用域取值,而不是“父作用域”。
當(dāng)一個(gè)函數(shù)被調(diào)用完成之后,其執(zhí)行上下文環(huán)境將被銷毀,其中的變量也會(huì)被同時(shí)銷毀。但是有些情況下,函數(shù)調(diào)用完成之后,其執(zhí)行上下文環(huán)境不會(huì)接著被銷毀。這就是需要理解閉包的核心內(nèi)容。
對(duì)于這個(gè)例子

function fn(){
    var max = 10;
    return function bar(x){
        if(x > max) {
            console.log(x);
        }
    };
}

var f1 = fn();
max = 100;
f1(15);//15

fn()調(diào)用完成。按理說應(yīng)該銷毀掉fn()的執(zhí)行上下文環(huán)境,但是這里不能這么做。注意,重點(diǎn)來了:因?yàn)閳?zhí)行fn()時(shí),返回的是一個(gè)函數(shù)。函數(shù)的特別之處在于可以創(chuàng)建一個(gè)獨(dú)立的作用域。而正巧合的是,返回的這個(gè)函數(shù)體中,還有一個(gè)自由變量max要引用fn作用域下的fn()上下文環(huán)境中的max。因此,這個(gè)max不能被銷毀,銷毀了之后bar函數(shù)中的max就找不到值了。

總結(jié):跟著大牛的文章,跟著理解,跟著寫代碼,終于把閉包理解了。但是,理論是學(xué)到了,真正用的時(shí)候還得要多思考。這種邏輯的碰撞就是程序員向前最大的鼓勵(lì)。謝謝大牛。
寫給自己的話:過早地開始關(guān)注細(xì)節(jié),你很可能錯(cuò)失上下文或整體信息。當(dāng)然,錯(cuò)失了細(xì)節(jié),也會(huì)讓你的理解僅僅停留在一些事物的表面。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/86304.html

相關(guān)文章

  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對(duì)方法,包括,,。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸耍虼宋闹兄豢炊?8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評(píng)論0 收藏0
  • 深入理解javascript原型閉包

    摘要:深入理解原型和閉包王福朋博客園深入理解原型和閉包一切都是對(duì)象原文鏈接本文要點(diǎn)一切引用類型都是對(duì)象,對(duì)象是屬性的集合。每個(gè)對(duì)象都有一個(gè),可稱為隱式原型。另外注意,構(gòu)造函數(shù)的函數(shù)名第一個(gè)字母大寫規(guī)則約定。 深入理解javascript原型和閉包 王福朋 - 博客園 —— 《 深入理解javascript原型和閉包》 1. 一切都是對(duì)象 原文鏈接:http://www.cnblogs.com...

    jemygraw 評(píng)論0 收藏0
  • 深入理解JavaScript,這一篇就夠了

    摘要:也就是說,所有的函數(shù)和構(gòu)造函數(shù)都是由生成,包括本身。如果只考慮構(gòu)造函數(shù)和及其關(guān)聯(lián)的原型對(duì)象,在不解決懸念的情況下,圖形是這樣的可以看到,每一個(gè)構(gòu)造函數(shù)和它關(guān)聯(lián)的原型對(duì)象構(gòu)成一個(gè)環(huán),而且每一個(gè)構(gòu)造函數(shù)的屬性無所指。 前言  JavaScript 是我接觸到的第二門編程語言,第一門是 C 語言。然后才是 C++、Java 還有其它一些什么。所以我對(duì) JavaScript 是非常有感情的,畢...

    villainhr 評(píng)論0 收藏0
  • JS筆記

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

    rottengeek 評(píng)論0 收藏0
  • 深入理解JavaScript原型閉包

    摘要:本文是本人閱讀學(xué)習(xí)深入理解原型和閉包時(shí)所作的總結(jié)和筆記,當(dāng)然也引用了很多原文,感興趣的朋友也可以直接去看原文。即這里的稱為隱式原型。注意,構(gòu)造函數(shù)的函數(shù)名第一個(gè)字母大寫規(guī)則約定。但實(shí)際上,上述情況是一種理想的情況。 本文是本人閱讀學(xué)習(xí)深入理解JavaScript原型和閉包時(shí)所作的總結(jié)和筆記,當(dāng)然也引用了很多原文,感興趣的朋友也可以直接去看原文。 1、一切都是對(duì)象 先說結(jié)論,一切引用類型...

    missonce 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<