我正在从本书的一个例子中练习java脚本并遇到以下
代码:在这里我学到了这个'这个' javascript中的关键字引用拥有代码的对象,其中'这个'关键字是。
function Vehicle1(theYear, theMake, theModel) {
var year = theYear;
var make = theMake;
var model = theModel;
this.getYear = function () { return year; };
this.getMake = function () { return make; };
this.getModel = function () { return model; };
}
Vehicle1.prototype.getInfo = function () {
return 'Vehicle1: ' + this.getYear() + ' ' + this.getMake() + ' ' + this.getModel();
}
代码二:我在这里学习使用IIFE(立即调用函数表达式)创建命名空间。
(function () {
this.myApp = this.myApp || {};
var ns = this.myApp;
var vehicleCount = 5;
var vehicles = new Array();
ns.Car = function () { };
ns.Truck = function () { };
var repair = {
description: 'changed spark plugs',
cost: 100
};
} ());
我应该单独执行上面的代码来理解作者试图解释的概念。但我最终在单个文件中执行这两个代码,我在第一个代码中收到错误消息
未捕获的TypeError:undefined不是函数Vehicle1.getInfo.myApp
问题是:IIFE函数为什么或如何尝试在代码1中放置或查找myApp命名空间?
如果我单独执行2个以上代码,则所有代码都按预期工作。
修改 这是完整的代码,只需使用脚本标记在html的主题部分中复制它。我在chrome中运行它并在控制台中查找错误详细信息
function Vehicle1(theYear, theMake, theModel) {
var year = theYear;
var make = theMake;
var model = theModel;
this.getYear = function () { return year; };
this.getMake = function () { return make; };
this.getModel = function () { return model; };
};
Vehicle1.prototype.getInfo = function () {
return 'Vehicle1: ' + this.getYear() + ' ' + this.getMake() + ' ' + this.getModel();
}
(function () {
this.myApp = this.myApp || {};
var ns = this.myApp;
var vehicleCount = 5;
var vehicles = new Array();
ns.Car = function () { };
ns.Truck = function () { };
var repair = {
description: 'changed spark plugs',
cost: 100
};
} ());
答案 0 :(得分:4)
我学到了这个' javascript中的关键字引用拥有代码的对象,其中'这个'关键字是。
事实并非如此,但似乎有点像。
警告 - 以下内容听起来很愚蠢。这是因为javascript this
是一个非常糟糕的语言功能(人们应该停止使用它)。
这是交易 - 这里并不是this
。至少不是你认为的那样。它真的是一个函数参数,就像其他任何函数一样。
让我告诉你。
让我们说你有这样的功能
function sayHi(firstName, lastName) {
console.log("Hi", firstName, " ", lastName);
}
这里有两种不同但非常相同的方式来调用它:
sayHi("Fred", "Flintstone");
sayHi.call(null, "Fred", "Flintstone");
这是因为所有函数都有call
方法。如果您愿意,可以使用.call
编写所有函数调用。
但首先null
参数是什么?那么,该参数是this
将被设置的参数。所以如果你有:
function sayHi(lastName) {
console.log("Hi", this, " ", lastName);
}
你可以说
sayHi.call("Fred", "Flintstone");
现在让我问你一个问题。如果您始终可以使用.call
编写所有函数,并且.call
将this
作为参数紧挨着其他参数,那么this
与其他任何参数的确切区别是什么?只是一个你不知名的人。
但sayHi(...)
格式对this
的影响是什么呢?由于我们没有直接指定它,它必须来自某个地方。好吧,在这种形式 - 这实际上只是call
的外观 - javascript 猜测你希望它是什么。这些规则并不复杂,但它仍然令人困惑。
如果您将其作为对象调用
var fred = "Fred";
fred.sayHi = sayHi;
fred.sayHi("Flintstone");
相当于
fred.sayHi.call(fred, "Flintstone");
在直接调用它的情况下:
sayHi("Flintstone");
规则规定它会猜测this
是全局window
对象。除非你处于严格模式,否则它将是undefined
(我认为,它可能是null
)。
sayHi.call(window, "Flintstone");
这是IIFE正在发生的事情。
基本上,this
是一个强大的功能,使其看起来更像Java,而且根本不需要语言。有些图书馆使用它,而你却没有选择权,但我总是向人们咨询当他们完全控制它时{。}}。
答案 1 :(得分:2)
JavaScript中的this
关键字是调用或执行函数的任何内容。在您的示例中,对于IIFE,this
将是全局Window
对象AKA window
您的问题似乎缺少代码。 Car
和Truck
是否应该延长Vehicle1
或其他内容?
你没有调用Vehicle1.getInfo.myApp
的代码,所以我不确定你是如何得到这条消息的。
答案 2 :(得分:2)
由于第一个代码后面缺少分号,导致组合文件以与预期不同的方式解释,因此出现错误。
让我们简化代码以查看结构。你有类似的东西:
getInfo = function () {
this.getYear();
}
(function () {
this.myApp = {};
} ());
在第一个函数之后没有分号,第二个函数周围的括号被视为给出调用第一个函数的参数:
getInfo = function () {
this.getYear();
}(function () {
this.myApp = {};
} ());
所以它基本上就像你写的那样:
function getInfo() {
this.getYear();
}
getInfo(function () {
this.myApp = {};
}());
在这两种情况下, this
都指向Window
(或全局对象),因为该函数未在实例上调用。您正在调用第二个函数,它将设置Window.myApp
,然后将其返回值(未定义)传递给getInfo
。 getInfo
将访问不存在的this.getYear
,因此您会收到类型错误。
我在这里得到的错误以及原始代码是:
TypeError:this.getYear不是函数
因为this
是全局对象,所以this.getYear
将是未定义的(不是函数)。