猿问

使用 Function 构造函数重写 Object.prototype 方法时出现范围错误

我试图重写Object.prototype.toString以添加其他类描述的功能。


这是初始代码:


(function(toString){

    Object.prototype.toString = function(){

        if(this instanceof TestClass)

        {

            return '[object TestClass]';

        }

        return toString.apply(this, arguments);

    }

})(Object.prototype.toString);


function TestClass(){}

var instance_obj = new TestClass();

Object.prototype.toString.call(instance_obj);

当我在控制台中运行它时,我得到以下输出:


[object TestClass]

好处是它不会彻底改变Object.prototype.toString工作方式,因此使用另一种类型[即不是 TestClass],事情会按预期工作,例如Object.prototype.toString.call(12)将输出[object Number].


到目前为止,这个实现没有任何问题。但是,我有另一个实现,代码如下:


(function(toString){

    var fn_code_str = `return function(){

        if(this instanceof TestClass)

        {

            return '[object TestClass]';

        }

            

        return toString.apply(this, arguments);

    }`;

    var pre_fn = new Function(fn_code_str);

    Object.prototype.toString = pre_fn();

})(Object.prototype.toString);


function TestClass(){}

var instance_obj = new TestClass();

Object.prototype.toString.call(instance_obj);


这似乎是 的递归问题toString.apply。但是,我不明白为什么第二个实现是递归的,如果第一个实现不是递归的?


注意if(this instanceof MyClassType){return '[object MyClassType]'}:第二个实现的原因是从数组中的类名列表动态添加不同类的类型检查代码[即]。换句话说,我不是修改每个新类的代码,而是将类名附加到数组中,然后自动生成条件语句。


繁星淼淼
浏览 94回答 1
1回答

翻过高山走不出你

问题是toStringIIFE 的参数不在new Function代码的范围内。相反,它使用全局toString== 。window.toStringObject.prototype.toString要解决此问题,您需要在 的代码toString中声明变量new Function以使返回的闭包起作用。作为一个简单的常数:(function() {    var pre_fn = new Function(`    const toString = Object.prototype.toString;//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    return function(){        if(this instanceof TestClass) {            return '[object TestClass]';        }                    return toString.apply(this, arguments);    }`);    Object.prototype.toString = pre_fn();})();或作为参数:(function() {    var pre_fn = new Function('toString', `//                            ^^^^^^^^^^^    return function(){        if(this instanceof TestClass) {            return '[object TestClass]';        }                    return toString.apply(this, arguments);    }`);    Object.prototype.toString = pre_fn(Object.prototype.toString);//                                     ^^^^^^^^^^^^^^^^^^^^^^^^^})();
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答