运用JavaScript闭包碰到的圈套(一)

运用JavaScript闭包碰到的圈套(一)

圈套:在类的原型对象中增加特权要领

起首定义一个Page类,该类中有一个私有变量dom:

function Page(){
    var dom;
}

定义2个特权要领来接见、修正私有变量dom:

function Page(){
    var dom;
    this.setDom=function(newDom){
        dom=newDom;
    };
    this.getDom=function(){
        return dom;
    }
}

然后我们对Page类举行测试:

var page1=new Page();
page1.setDom("<div>page1<div>");
console.log(page1.getDom());//<div>page1<div>
var page2=new Page();
page2.setDom("<div>page2</div>");
console.log(page2.getDom());//<div>page2</div>
console.log(page1.getDom());//<div>page1<div>

到目前为止,Page类一般事情。
这时刻题目来了:我想每一个Page类的对象都有雷同的特权要领,那就将这两个特权要领增加到Page的原型对象中好了。

function Page(){
    var dom;
    if(this.__proto__.setDom !== "function"){
        this.__proto__.setDom=function(newDom){
            dom=newDom;
        };
        this.__proto__.getDom=function(){
            return dom;
        };
    }
}

对修正后的Page类举行测试:

var page1=new Page();
page1.setDom("<div>page1<div>");
console.log(page1.getDom());//<div>page1<div>
var page2=new Page();
page2.setDom("<div>page2</div>");
console.log(page2.getDom());//<div>page2</div>
/*
    注重!题目涌现了!
*/
console.log(page1.getDom());//<div>page2<div>

这时刻末了一行的console.log(page1.getDom())打印的效果变成了<div>page2<div>

探讨

条件

  1. 在运用new操纵符挪用Page组织函数建立对象的历程:先建立一个Page类的空对象,并将组织函数中的this指向该对象,再实行组织函数。

  2. 在函数中定义的变量都保存在该函数实行环境变量对象中。

  3. 每一个函数都有一个作用域链。函数在定义时,就会天生不完全的作用域链,该作用域的前端是函数定义时地点环境变量对象。函数在实行时,会建立该函数的实行环境,并将该实行环境的运动对象(这里可理解为变量对象)增加到之前建立的作用域链的前端,此时的作用域链是完全的作用域链。

  4. 变量接见的历程就是从作用域链家前端沿着作用域链查找变量的历程。

剖析

  1. Page类的组织函数运用动态原型的体式格局来给原型对象增加要领。因此在建立第一个Page实例时,挪用Page函数建立实行环境a,这时刻,会在a中定义setDomgetDom要领并增加到Page类的原型对象中。原型对象中的setDomgetDom要领的作用域链前端都是实行环境a(正确的说是a对应的变量对象)。

  2. 建立第一个Page实例时,给Page类的原型对象增加了setDomgetDom要领。以后再建立其他的Page实例时,都不会再修正原型对象中的setDomgetDom要领了。

  3. 在建立第二个Page实例时,再次挪用Page函数,建立了实行环境b。

  4. 在挪用Page实例的setDomgetDom要领时,因为都是挪用原型对象中的要领。而依据之前说的,原型对象中的setDom要领和getDom要领在接见dom变量的时刻,都要沿着作用域链查找,末了找到的是环境a中的变量dom,也就是第一个Page实例的私有变量dom

  5. 所以在测试的时刻,无论是page1照样page2挪用setDomgetDom要领,都是修正或接见page1中的私有变量dom

小结

在类的原型对象中增加的特权要领,不能用来接见或操纵类的私有变量,只能用来接见或操纵this润饰的特权变量。

    原文作者:homer1011110
    原文地址: https://segmentfault.com/a/1190000005129452
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞