JavaScript闭包和类实现
我编写了以下代码来理解JavaScript中类实现和闭包 1. 在这里,当我实例化JavaScript闭包和类实现,javascript,closures,Javascript,Closures,我编写了以下代码来理解JavaScript中类实现和闭包 1. 在这里,当我实例化Person时,我得到以下输出- Person Fired!! EchoMyName - Self Called ReferenceError: EchoMyName is not defined 但它就在那里,我在调用它之前就定义了它?为什么会出错 2. 另外,当我修改代码以删除以前的错误并对某人调用CallMe时,它似乎无法访问EchoMyName function Person(name) { th
Person
时,我得到以下输出-
Person Fired!!
EchoMyName - Self Called
ReferenceError: EchoMyName is not defined
但它就在那里,我在调用它之前就定义了它?为什么会出错
2.
另外,当我修改代码以删除以前的错误并对某人调用CallMe
时,它似乎无法访问EchoMyName
function Person(name) {
this.Name = name;
console.log("Person Fired!!");
function EchoMyName(temp) {
console.log("EchoMyName - " + temp);
};
}
Person.prototype.CallMe = function(){
console.log("Call Me Fired!");
EchoMyName("Called by CallMe!");
}
呼叫:
new Person().CallMe();
输出
Person Fired!!
Call Me Fired!
ReferenceError: EchoMyName is not defined
更新#1
谢谢你的回答。我在Douglas Crockford的网站上找到了这个链接:
它提供了对JavaScript中隐藏的信息的非常清晰的理解
但它就在那里,我在调用它之前就定义了它?为什么会出错
区别在于如何计算函数
定义
在第一个代码段中,EchoMyName
是一个字符串,因为它周围有括号。允许立即调用它们,但只能在它们自己的主体中通过它们的名称引用它们
在第二个示例中,EchoMyName
是一个。这些都是受限制的,允许他们在自己的身体之外被他们的名字引用
它似乎无法访问EchoMyName
function Person(name) {
this.Name = name;
console.log("Person Fired!!");
function EchoMyName(temp) {
console.log("EchoMyName - " + temp);
};
}
Person.prototype.CallMe = function(){
console.log("Call Me Fired!");
EchoMyName("Called by CallMe!");
}
这是因为EchoMyName
绑定到Person
内的范围。除此之外,EchoMyName
不存在
您需要通过this
或Person.prototype
将EchoMyName
附加到实例,以便CallMe
可以访问它:
this.EchoMyName = function EchoMyName(temp) {
console.log("EchoMyName - " + temp);
};
或者,如果您希望保持EchoMyName
的作用域,以便其他代码无法调用它,那么CallMe
也需要在相同的作用域函数中定义。不过,这不一定是个人
:
var Person = (function () {
function Person(name) {
this.Name = name;
console.log("Person Fired!!");
}
function EchoMyName(temp) {
console.log("EchoMyName - " + temp);
}
Person.prototype.CallMe = function () {
console.log("Call Me Fired!");
EchoMyName("Called by CallMe!");
};
return Person;
})();
参考:
这是一个函数表达式,不是函数定义;名称EchoMyName
仅指函数本身内部的函数,因此以后不能使用它。(除了IE的JScript,它是有缺陷的。)
你的第二个问题源于这样一个事实:你所拥有的不是一门课;这是一个函数。可以在JavaScript中的函数中声明函数,并且它的作用域将限定为该函数,就像正则变量一样(但被提升,以便可以在函数中的任何点使用)。原型只是一个对象,不能访问构造函数的局部变量
总之,在ECMAScript 5中:
- 只有三个作用域:
- 全球的
- 作用
catch
- 在命名函数表达式中,名称只能由该函数访问
- 对于正则变量,范围没有例外;如果原型上的函数需要目标函数的某些内容(如果它们不需要,为什么它们在原型上?)
- 如果没有括号,函数表达式看起来像函数声明,它的作用类似于同一范围内的变量,但被“提升”,因此无论它出现在函数中的何处,它的作用就像它在开始时出现一样
代码片段#1
发生引用错误的原因是以下代码:EchoMyName(“被人调用”)代码>
EchoMyName
是一个自调用函数,位于名为Person
的JavaScript构造函数的作用域内。一旦它被自调用,它就不再存在。如果我们使用的是另一种编程语言,我们可以将其类比为匿名对象
在JavaScript中,函数实际上是对象。声明函数时,您正在创建对象的实例
下面是声明函数的几种不同方法
//function statement
function x (a, b) { return a + b; }
//function expression, this will store an anonymous function into a variable
var y = function (a, b) { return a + b; };
//Function constructor
var z = new Function ("a", "b", "return a + b;"); // avoid this form, it will prevent certain optimizations from the browser's JS engine because of the strings (this is just an example)
代码片段#2
在JavaScript函数中声明变量或函数时,它仅限于函数的范围。构造函数也是如此
您需要声明一个函数表达式并将其存储在Person
构造函数的属性中
下面是一个小例子
function Person(name) {
this.Name = name;
console.log("1 Person Fired!!");
// notice that function is stored in this.EchoMyName
this.EchoMyName = function(temp) {
console.log("2 EchoMyName - " + temp);
};
console.log("3 Still in Person!")
}
Person p = new Person("Bob");
p.EchoMyName("Hello World!");
输出:
1 Person Fired!!
3 Still in Person!
2 EchoMyName - Hello World!
原型
在JavaScript中,没有像在许多其他面向对象语言(C++、C#、Java)中那样的传统继承。您所拥有的是对象链接
如果我们以您的代码为例,Person构造函数将在名为prototype的属性中存储一个阴影对象。Person的每个实例都将引用相同的原型。此外,原型的原型是对象
我邀请您阅读来自Mozilla开发者网络的文章,以了解更多信息。在第一个版本中,EchoMyName
名称的作用域是函数本身,在封闭的作用域中不可用。这是因为它是一个命名函数表达式,而不是函数声明。在第二个版本中,您试图在创建它的变量范围之外的变量范围内调用EchoMyName
。.prototype
方法不继承构造函数的变量范围。。。实际上,最后定义的函数不是有效的语法。@CrazyTrain:谢谢你更正了语法。你应该返回函数。这很清楚,谢谢。但我有一个疑问。如果我使用this
创建EchoMyName
它将可以访问Person()
中的局部变量,但是如果我将它定义为Person()
之外的原型,我就无法访问这些局部变量,对吗?Person()
中定义的原型是否可以访问其局部变量?prototype
上的@AbijeetPatro方法应独立于与它们相关的任何实例或闭包。因此,您需要避免从构造函数内部更改原型。如果方法依赖于构造函数作为
//function statement
function x (a, b) { return a + b; }
//function expression, this will store an anonymous function into a variable
var y = function (a, b) { return a + b; };
//Function constructor
var z = new Function ("a", "b", "return a + b;"); // avoid this form, it will prevent certain optimizations from the browser's JS engine because of the strings (this is just an example)
function Person(name) {
this.Name = name;
console.log("1 Person Fired!!");
// notice that function is stored in this.EchoMyName
this.EchoMyName = function(temp) {
console.log("2 EchoMyName - " + temp);
};
console.log("3 Still in Person!")
}
Person p = new Person("Bob");
p.EchoMyName("Hello World!");
1 Person Fired!!
3 Still in Person!
2 EchoMyName - Hello World!