下面的示例代码是 John Resig 的 Learning Advnaced JavaScript 中的#36。 http://ejohn.org/apps/learn/#36
It is called We need to make sure the new operator is always used.
六个问题 - 如果您能提供尽可能详细的信息,我将不胜感激
1) function User
是否真的在这段代码中调用过?我注意到当它说 assert(user...)
时,user 是小写的。如果函数被调用,如何调用?当它断言变量 user 时它会被调用吗,它附加了一个函数调用,即 User("John,"name)
2) 如果我假设函数 User 从未被调用是正确的,有没有办法运行代码
this.name = first + ""+ last;`?
3) 如果函数 User 被调用,或者如果它被调用,你能解释一下函数 User 内部的操作顺序吗?例如,它在执行之前返回新用户 this.name = first + ""+ last;
如果此函数被调用或被调用,那将如何工作?
4) !(this instanceof User)
如果为真,会以何种方式。由于函数 User 是对象,“this”不会总是它自己的一个实例吗?
5) 关于第一个断言,即 assert(user, "this was defined correctly, even if it was by mistake")
,你能解释一下它是如何被正确定义的吗,重要的是,请解释这是怎么个错误?应该怎么做才不会出错?
6) 关于第二个断言,为什么保持正确的名称是值得注意的?是不是变量
name已经赋值
Resig 这么简单。您预计名称会以何种方式更改?
function User(first, last){
if ( !(this instanceof User) )
return new User(first, last);
this.name = first + " " + last;
}
var name = "Resig";
var user = User("John", name);
assert( user, "This was defined correctly, even if it was by mistake." );
assert( name == "Resig", "The right name was maintained." );
最佳答案
这个例子展示了 JavaScript 设计中的一个基本缺陷,即在没有 new
的情况下调用旨在用作构造函数的函数。运算符可能导致全局对象的意外修改。
User
在此行调用:var user = User("John", name);
.小写user
持有对新大写字母User
的引用实例。参见 #1。
如果
User
在没有new
的情况下调用, 然后this
不会是instanceof
User
.发生这种情况时,我们立即调用new User(...)
.在第二次调用中,this
将是instanceof
User
,所以条件 block 被跳过,我们只是继续构造函数,创建一个新的User
实例。正如最初预期的那样。当调用时没有
new
运算符,this
的值在函数中简单地引用全局对象,即window
在浏览器中。这是 JavaScript 设计中的一个严重错误,本练习将演示解决方法。因为
User
没有显式返回构造函数(没有instanceof
检查 block ),如果User
在没有new
的情况下被调用它会返回undefined
和assert
会失败。instanceof
检查可防止这种情况。没有
instanceof
的保护检查,打电话User
没有new
会导致意想不到的结果。自this
会引用window
, 分配给this.name
会更新window.name
, 而不是name
新属性User
实例,以及assert
会失败。
关于javascript - 使用新的运算符——来自 John Resig #36,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5346951/