- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
假设我有一个对象构造函数和一个原型(prototype)方法,例如:
function Human(name) {
this.name = name;
}
Human.prototype.sayName = function(){
console.log('my name' + this.name);
};
在我的代码的其他地方,我定义了一个 human 的实例:
let jeff = new Human('jeff');
最后我想将 jeff.sayName
作为回调传递给其他一些函数,比如(对于一个特别简单的例子)
function callFunction(callback) {
callback();
}
callFunction(jeff.sayName);
当我在上面调用 callFunction(jeff.sayName)
时,上下文需要绑定(bind)到 jeff
本身,比如调用函数(jeff.sayName.bind(jeff))
。但这很笨拙,我不想每次使用此方法作为回调时都担心这种逻辑。
另一种方法是将 Human.prototype.sayName
替换为类似
Human.prototype.createSayName = function(context){
return function() {
console.log(context.name);
};
};
然后用
定义函数jeff.sayName = jeff.createSayName(jeff)
但这有点尴尬,我想让 jeff
不知道它从 Human.prototype
继承的方法。
所以理想情况下我想在 Human.prototype 本身上处理这个逻辑,比如
Human.prototype.sayName.bind(WhateverObjectHoldsThisMethod)
但我不知道 javascript 有办法做到这一点。
TL;DR 我想要一种将对象的原型(prototype)方法绑定(bind)到继承它的任何对象的方法,而不必在每次将该方法作为参数传递或每次定义新对象时都这样做。对不起,如果这没有什么意义。谢谢!
最佳答案
由于词法环境、作用域解析、原型(prototype)继承和环境记录在 JavaScript 中的工作方式,如果不修改调用回调函数的函数,您所要求的是不可能的。
但是,您可以使用箭头函数来调用您希望的 Human#sayName
引用,而不是将 Human#sayName
引用作为回调传递打电话。
它并不完美,但它简单、干净且可读。
function Human(name) {
this.name = name;
}
Human.prototype.sayName = function(){
console.log('my name' + this.name);
};
let jeff = new Human('jeff');
function callFunction(callback) {
callback();
}
callFunction(_ => jeff.sayName());
为了更好地理解我之前提到的那些花哨的词,以及它们在 JavaScript 中的工作原理,我建议阅读 ECMAScript 2017 Language Specification 的第 8.1 节。 .第 8.1.1.3 小节包含您要查找的特定信息,但到该部分的其余部分对于理解该小节是必要的。
基本上,当您将 Human#sayName
传递给 callFunction
时,您传递的是对原始 sayName
函数的引用,因此您可能以及这样做:(请原谅双关语)
function callFunction(callback) {
callback();
}
callFunction(function(){
console.log('my name' + this.name);
});
函数的内容在执行之前不会被评估,这意味着在执行时,this
的值已经改变。雪上加霜的是,原始函数不知道您通过哪个实例请求它。它实际上从未存在于 jeff
对象上。它存在于函数对象的原型(prototype)中,当您执行对象属性查找时,JavaScript 引擎搜索原型(prototype)链以找到该函数。
您很可能会得到您所要求的行为,但不会受到您所设置的约束。例如,如果函数不必存在于原型(prototype)链上,而是可以存在于实例上(请记住,这会为每个实例创建一个新的函数对象,因此会增加成本),您可以定义函数在构造函数中,然后使用不会被覆盖的标识符存储对正确 this
的引用:
function Human(name) {
const _this = this;
this.name = name;
this.sayName = function(){
console.log('my name' + _this.name);
};
}
let jeff = new Human('jeff');
function callFunction(callback) {
const _this = { name: 'hello' }; // does not affect output
callback();
callback.call(_this); // does not affect output
}
callFunction(jeff.sayName);
这将是一个更安全的选择,因为您知道 _this
将始终引用您期望它在构造函数上下文中引用的对象,即在该函数中定义的所有函数对象对象将继承其父作用域的标识符,并且这些标识符不会受到调用上下文的影响。
或者,您可以更进一步,根本不依赖 this
的值:
function Human(name) {
const sayName = function(){
console.log('my name' + name);
};
Object.assign(this, { name, sayName });
}
let jeff = new Human('jeff');
function callFunction(callback) {
const name = 'hello'; // does not affect output
callback();
callback.call({ name: 'world' }); // does not affect output
}
callFunction(jeff.sayName);
这样做的好处是:
this
的值是多少。关于javascript - 我可以将构造函数的原型(prototype)方法绑定(bind)到构造的实例,同时保持关注点分离吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47897716/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!