使用新的操作员 - 来自John Resig#36

mjm*_*che 6 javascript

下面的示例代码是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)如果我m correct in assuming that function User is never called, is there a way that the codethis.name = first +""+ last;`运行?

3)如果调用函数User,或者如果要调用它,可以解释函数User内的操作顺序.例如,this.name = first + " " + last;如果调用此函数或调用此函数,它会在返回之前返回新用户吗?

4)!(this instanceof User)如果是真的,以什么方式.由于函数User是对象,不会"这个"总是它自己的一个实例吗?

5)关于第一个断言,即assert(user, "this was defined correctly, even if it was by mistake"),你可以解释它是如何被正确定义的,重要的是,请解释它是如何错误的?它应该如何完成所以它不是一个错误?

6)关于第二个断言,为什么保持正确的名称是值得注意的?Isn t it as simple as variable名字having been assignedResig`.您可能以何种方式改变名称?

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." );
Run Code Online (Sandbox Code Playgroud)

Way*_*ett 3

这个例子展示了 JavaScript 设计中的一个基本缺陷,即调用不带运算符的用作构造函数的函数new可能会导致全局对象的无意修改。

  1. User在这一行被称为:var user = User("John", name);。Lowercaseuser保存对新的 Uppercase 实例的引用User

  2. 参见#1。

  3. 如果User称为 without new,则this不会是 an instanceof User。发生这种情况时,我们立即致电new User(...)。在第二次调用中,this 将是一个instanceof User,因此条件块被跳过,我们只需继续构造函数,User按照最初的预期创建一个新实例。

  4. 当不使用运算符调用它时new,函数中的值仅引用浏览器中的this全局对象。window这是 JavaScript 设计中的一个严重错误,本练习演示了一种解决方法。

  5. 因为构造函数没有显式返回User(没有instanceof检查块),所以如果User在没有它的情况下调用,new则会返回undefined并且assert会失败。检查instanceof可以防止这种情况发生。

  6. 如果没有检查的保护instanceofUser没有检查的调用new会导致意想不到的结果。由于thiswill 引用window,因此对 的赋值this.name将更新window.name,而不是nameUser实例的属性,并且assert将会失败。