为什么Nodejs中不能给call, apply声明变量?
为什么Nodejs中不能给call, apply声明变量?
var getTypeStr = Object.prototype.toString.call;
getTypeStr({}); // 你认为结果是什么?
为什么呢?
当然可以。让我们来详细探讨一下这个问题,并通过示例代码进行说明。
问题背景
在Node.js中,call
和 apply
是 JavaScript 函数对象的内置方法,用于改变函数执行时的上下文(即 this
的值)。通常情况下,call
和 apply
用于调用一个函数并传入特定的参数或参数数组。
示例代码
var getTypeStr = Object.prototype.toString.call;
console.log(getTypeStr({})); // 输出: "[object Object]"
问题核心
问题是,当我们尝试将 Object.prototype.toString.call
赋值给一个变量 getTypeStr
后,再调用 getTypeStr
,它不会像我们预期的那样工作。原因在于 Object.prototype.toString.call
是一个绑定到特定对象的方法调用,而当我们将其赋值给一个新变量时,这个绑定关系被打破了。
原因分析
Object.prototype.toString
是一个函数,但当我们使用 call
方法时,它实际上是在 Object.prototype
上的一个方法调用。当我们将 Object.prototype.toString.call
赋值给 getTypeStr
变量时,我们只是复制了这个方法的引用,而不是复制它的上下文(即 this
指向的对象)。
因此,当我们调用 getTypeStr({})
时,this
在内部不再是 Object.prototype
,而是默认指向全局对象(在浏览器中是 window
,在 Node.js 中是 global
),这会导致错误的结果。
解决方案
为了正确地使用 call
或 apply
,我们应该在调用时显式地传递上下文:
var getTypeStr = function (obj) {
return Object.prototype.toString.call(obj);
};
console.log(getTypeStr({})); // 正确输出: "[object Object]"
或者,我们可以直接使用箭头函数来保持正确的上下文:
const getTypeStr = obj => Object.prototype.toString.call(obj);
console.log(getTypeStr({})); // 正确输出: "[object Object]"
通过这种方式,我们可以确保 this
在调用 Object.prototype.toString.call
时始终指向正确的对象。这样,无论是在浏览器还是在 Node.js 环境中,我们都能得到预期的结果。
toString.call 他是基于构造函数去调用的, 也应该算是函数内部的. 所以你根本没有必要纠结这个问题. 他就是这么特殊.
根据ecma-262的规范,call方法需要在func对象上调用。当IsCallable(func)为false的时候,会抛出TypeError。所以chrome中的错误是:TypeError: undefined is not a function
http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.4.4
var type = function(obj) {
var map = {
'[object Array]': 'array',
'[object Object]': 'object',
'[object String]': 'string',
'[object Number]': 'number',
'[object Boolean]': 'boolean',
'[object Null]': 'null',
'[object Function]': 'function'
};
var t = Object.prototype.toString.call(obj);
return map[t];
}
根据你代码的意思,你可能是需要类似于这种功能。希望对你有帮助。
炒冷饭的bind