使用原型方法访问构造函数中的变量

时间:2013-11-22 21:26:55

标签: javascript constructor prototype

为什么我不能使用原型方法访问构造函数中的变量HTML .nextSlide?

function test(root){

    var HTML = getAllHTML();

    function getAllHTML(){

        var boss, expoHTML;
        var boss = document.querySelector(root);

        expoHTML = {

            slides: boss.querySelectorAll(".slide"),
            prev: boss.querySelector(".control.prev"),
            next: boss.querySelector(".control.next"),
            current: boss.querySelector(".slide-current"),
            total: boss.querySelector(".slide-total")

        }

        return expoHTML;

    }


}


EXPOjs.prototype.nextSlide = function(){

    alert(HTML.current)

}


var newTEST = new test(".ieps");
newTEST.nextSlide();

2 个答案:

答案 0 :(得分:1)

这是一个“范围”问题; Javascript中的每个变量都有一个范围,这意味着:“谁可以看到这个变量”?

在您的情况下,HTML在函数test()中定义。这意味着它将可见:

  • 在函数test()
  • test()
  • 中定义的任何函数中

就是这样。在test()之外,HTML将为空。

现在,我可以看到你使用test()作为构造函数。有了这个,你就进入了对象创造的奇妙世界和Javacript。深吸一口气:D

执行此操作时:

function Person( age ){
  this.age = age;
}

然后你这样做:

var pavlo = new Person( 23 );

基本上“新”具有以下效果:

  • 创建空对象
  • 运行您的函数,以便this指向新创建的对象
  • 将新创建的对象分配给pavlo

这种诡计意味着你可以做到

var pavlo = new Person( 23);
console.log( pavlo.age );

然后有原型功能。 如果您定义这样的函数:

Person.prototype.setAge = function( newAge){
   this.age = newAge();
}

使用该构造函数创建的任何对象也可以访问Person's prototype对象中定义的任何函数(或该任何变量)。另外,this变量将是进行该调用的对象。

所以,如果你有:

function Person( age ){
  this.age = age;
}

Person.prototype.setAge = function( newAge){

   `this` at this point is the object "calling"
   this.age = newAge();
}

var pavlo = new Person( 23 );
console.log( pavlo.age );

// pavlo is making the call. So, within `setAge()`, `this` will be `pavlo`
pavlo.setAge( 26 );

所以,对于你的解决方案:

function test(root){
  this.HTML = getAllHTML();
  // etc.
}

然后你的警报应该是:

test.prototype.nextSlide = function(){
  alert(this.HTML.current);
}

请注意,在Javascript中,您应该使用以大写字母开头的构造函数(请参阅:Test而不是test)。

如果您不希望从外部访问HTML,则惯例表示您通常在变量名称前加上下划线(称之为_HTML)。

如果您必须将该变量隐藏在开发人员之外,那么 其他方式。然而,它并不是那么简单 - 大多数开发人员会说 - 绝对不值得努力。

一些好的读物(但是,我必须说当我开始使用JS时,我会读到它们,他们当时混淆了我的想法:D)

更新:这是关于此事的另一篇精彩文章:https://blog.jcoglan.com/2012/01/19/the-cost-of-privacy

享受!

答案 1 :(得分:0)

您正在尝试访问Test中的属性,但是test不属于Expojs。然后,您尝试扩展Expojs的原型,这不是一个好主意,因为为您无法控制的代码创建新成员永远不是一个好主意。

如果要使nextSlide成为Test的一部分,则必须使用Test.prototype.nextSlide(),这将为测试对象创建一个名为nextSlide()的新原型成员。然后可以访问公共实例成员,例如this.getallHTML = function(){// usual stuff};

您需要将此关键字用于要在基本级别上访问的变量。 之后,如果要保护代码免遭他人错误使用,则必须考虑抽象问题。

我刚刚做了很多关于javascript中面向对象的教程,正如您所看到的,到目前为止,我已经学到了有关此方面的负载(仍在学习中,所以我可能在这里没有所有的东西),但是我建议做更多一些学习。