JavaScript 工厂模式变量作用域

11 浏览
0 Comments

JavaScript 工厂模式变量作用域

我正在跟随一个教程,学习在javascript中使用工厂模式创建对象。下面的代码让我困惑,不知道为什么它可以工作。








我认为第一行注释的代码(在showLabel函数中使用this关键字)是正确的。使用obj替代它,我不确定为什么它可以工作。obj必须引用某个全局变量,因为在该函数运行时,没有定义obj,对吧?由于我创建了2个对象,不仅仅是这个例子的运行结果好,obj的内容的旧值也被存储并且正确地被引用。但是,如何做到的呢?如果我取消第二行注释,它就会出问题,我明白为什么,因为我在明确告诉js我正在谈论一个本地变量,而实际上并没有。

admin 更改状态以发布 2023年5月21日
0
0 Comments

showLabel函数中的obj之所以有效,是因为它是一个局部变量。每次调用create address时,该函数被声明。在JavaScript中,我们称之为闭包。

一般来说,原型对象的创建比使用工厂模式更受欢迎。

现在看看这个原型示例:

var Address = function(street, city, state, zip){
    this.street = street;
    this.city = city;
    this.state = state;
    this.zip= zip;
};
Address.prototype.showLabel = function(){
    alert(this.street + "\n" + this.city + ", " + this.state + " " + this.zip);
}

现在,当我使用new关键字创建新地址时:

// create new address
var address = new Address('1', '2', '3', '4');
address.showLabel(); // alert

代码将表现出您期望的行为。但是,如果我不使用new关键字,则构造函数中的this实际上是window对象。

// create new address
var address = Address('1', '2', '3', '4'); // address == undefined
window.showLabel(); // address was added to window

我希望这可以帮助您理解一些事情。

0
0 Comments

欢迎来到闭包的世界。你对感觉什么感觉是对的,因为闭包的表现就好像是全局变量,但又不完全是全局变量。这就是闭包的行为。

在JavaScript中,当函数返回时,并不是所有的局部变量都像Java或C中一样会被垃圾回收/释放。如果有对该变量的引用,那么该变量将在其定义的函数作用域中存活。

从技术上讲,机制是不同的,有些人试图用这种方式来解释它,最终却混淆了许多其他人。对我来说,闭包是一种“私有”全局变量,就像全局变量一样,它们是在函数之间共享的,但它们没有声明在全局作用域中。就像你在遇到这个功能时所描述的感觉一样。

这里是我在stackoverflow上关于JavaScript闭包的一些其他答案,我认为值得一读:

JavaScript的隐藏特性?

请解释JavaScript循环中闭包的用途

或者你可以通过搜索“JavaScript闭包”来探索这个主题。


附加答案。

至于为什么this在你的代码中起作用的解释(而不是尝试更正你的代码,以使this可以起作用,即使在未更正的版本中它也是有效的 *咳咳* ;-):

JavaScript有延迟绑定。非常晚,非常非常晚。在编译时this不仅没有绑定,在运行时也没有绑定。它是在执行时绑定的,也就是说直到函数被调用时,你才能知道this实际上指向什么。调用者基本上决定了this的值,而不是使用this的函数。

一些神奇的JavaScript后期绑定操作:

function foo () {
    alert(this.bar);
}
var bar = "hello";
var obj = {
    foo : foo,
    bar : "hi"
};
var second_obj = {
    bar : "bye"
};
foo(); // says hello, 'this' refers to the global object and this.bar
       // refers to the global variable bar.
obj.foo(); // says hi, 'this' refers to the first thing before the last dot
           // ie, the object foo belongs to
// now this is where it gets weird, an object can borrow/steal methods of
// another object and have its 'this' re-bound to it
obj.foo.call(second_obj); // says bye because call and apply allows 'this'
                          // to be re-bound to a foreign object. In this case
                          // this refers to second_obj

在你的代码中,this 方便地引用调用函数的对象作为其方法,这就是为什么它可以工作,即使你似乎没有使用所谓的正确构造函数语法。

0