[JavaScript] Uncaught TypeError: Method get Set.prototype.size called on incompatible receiver

在对Set进行方法扩展的时候,无法覆盖size属性

情景:定义一个SingletonSet,继承自Set,size只能为1,并且不能add和remove

//首先是extend函数

var extend = (function () {
    //检查是否存在bug
    for (var p in {
            toString: null
        }) {
        //如果进来了,那说明没有bug
        return function extend(o) {
            for (var i = 1; i < arguments.length; i++) {
                var source = arguments[i];
                for (var prop in source) {
                    // var desc = Object.getOwnPropertyDescriptor(source, prop);
                    // Object.defineProperty(o, prop, desc);
                     o[prop] = source[prop];  //书上的例子,
                }
            }
            return o;
        }
    }

    //如果存在bug的话
    return function patched_extend(o) {
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];

            //复制可以枚举的属性
            for (var prop in source) {
                // var desc = Object.getOwnPropertyDescriptor(source, prop);
                // Object.defineProperty(o, prop, desc);
                 o[prop] = source[prop];
            }

            //检查特殊属性并进行复制
            for (var j = 0; j < protoprops.length; j++) {
                prop = protoprops[j];
                if (source.hasOwnProperty(prop)) {
                    // var desc = Object.getOwnPropertyDescriptor(source, prop);
                    // Object.defineProperty(o, prop, desc);
                    o[prop] = source[prop];
                }
            }
        }
        return o;
    }
    var protoprops = ["toString", "valueOf", "constructor",
        "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable",
        "toLocalString"
    ];
}());

//调用
function SingletonSet(member) {
    this.member = member;
   this.size =2;
}

SingletonSet.prototype = inherit(Set.prototype);

extend(SingletonSet.prototype, {
    constructor: SingletonSet,
    add: function () {
        throw "read-only set"
    },
    remove: function () {
        throw "read-only set"
    },
     get size(){
        return 1;
    },
    foreach:function(f,context){
        f.call(context,this.member);
    },
    contains:function(x){
        return x===this.member;
    }

});

var newSet = new SingletonSet(1);

console.log(newSet.size); //打印

打印出来发现newSet的size属性报错如下:

之后通过排查,在extend函数中 该位置进行打印测试:


  for (var prop in source) {
                // var desc = Object.getOwnPropertyDescriptor(source, prop);
                // Object.defineProperty(o, prop, desc);
                 o[prop] = source[prop];
                 console.log(prop);
                 console.log(o[prop]);
            }

打印如下:

也就是说,是在执行o[prop] = source[prop];时,当prop===‘size‘时,因抛出错误,并未将自定义的方法赋值给目标对象。

所以,我的解决办法,也就是注释掉的那两句,通过Object.defineProperty来进行方法的复制,从而避免使用o[‘size‘]而抛出错误。

修改后的extend函数如下

var extend = (function () {
    //检查是否存在bug
    for (var p in {
            toString: null
        }) {
        //如果进来了,那说明没有bug
        return function extend(o) {
            for (var i = 1; i < arguments.length; i++) {
                var source = arguments[i];
                for (var prop in source) {
                     var desc = Object.getOwnPropertyDescriptor(source, prop);
                     Object.defineProperty(o, prop, desc);
                    // o[prop] = source[prop];  //书上的例子,
                }
            }
            return o;
        }
    }

    //如果存在bug的话
    return function patched_extend(o) {
        for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];
            //复制可以枚举的属性
            for (var prop in source) {
                var desc = Object.getOwnPropertyDescriptor(source, prop);
                 Object.defineProperty(o, prop, desc);
                 //o[prop] = source[prop];
            }

            //检查特殊属性并进行复制
            for (var j = 0; j < protoprops.length; j++) {
                prop = protoprops[j];
                if (source.hasOwnProperty(prop)) {
                    var desc = Object.getOwnPropertyDescriptor(source, prop);
                    Object.defineProperty(o, prop, desc);
                    //o[prop] = source[prop];
                }
            }
        }
        return o;
    }

    var protoprops = ["toString", "valueOf", "constructor",
        "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable",
        "toLocalString"
    ];
}());

此时


var newSet = new SingletonSet(1);

console.log(newSet.size); //打印

//结果 为 1,符合预期

原文地址:https://www.cnblogs.com/ForRickHuan/p/9441983.html

时间: 2024-10-21 08:05:35

[JavaScript] Uncaught TypeError: Method get Set.prototype.size called on incompatible receiver的相关文章

[Android]通过js方法回调部分native报错 Web Console: Uncaught TypeError: Object [object Object] has no method &#39;xxx&#39;

在android4.2以前,注入步骤如下: webview.getSetting().setJavaScriptEnable(true); class JsObject { public String toString() { return "injectedObject"; } } webView.addJavascriptInterface(new JsObject(), "injectedObject"); Android4.2及以后,注入步骤如下: webv

android webView 图片加载不出来 后台报错Uncaught TypeError: Cannot call method &#39;getElementsByTagName&#39; of null

在之前,webView加载图片完全没有问题.直到前端H5开发换新的加载图片的方式,导致图片忽然加载不出来了. 从后台日志看到了webview 打印了报错信息 Cannot call method 'getElementsByTagName' of null 我怀疑是不是由于此处报错终止了图片加载的进程. 分析此处错误出现的原因: 由于调用的H5界面的js其中的写法不规范,webView在加载的时候,调用的doom模型为空,导致了其图片没有加载出来 解决办法: 在客户端webView.getSet

Javascript报uncaught typeerror illegal invocation错误

今天在写js代码的时候遇到一个奇怪的错误,uncaught typeerror illegal invocation. 这个错误以前一直没遇到过,不知道是什么问题,于是我仔细看我的代码,才发现是因为自己粗心,在用ajax向后台传值的时候把一个对象当作参数传上去了,所以才会报这个错误...简直无语了,以后不能粗心大意啊..   这么低级的错误啊..在这里记录一下,以免下次再犯... 版权声明:本文为博主原创文章,未经博主允许不得转载.

javascript Class.method vs Class.prototype.method(类方法和对象方法)

在stackoverflow上看到一个这样的提问,以下代码有什么区别? Class.method = function () { /* code */ } Class.prototype.method = function () { /* code using this.values */ } 看来确实有很多人和我一样对这个问题有疑问,实际上这个牵涉到static和dynamic方法的概念. Class.method这种模式定义的method是绑定在Class对象之上的.在js中,我们知道一切皆

Uncaught TypeError: download is not a function at HTMLAnchorElement.onclick (index.html:25)

前段时间调试html报了这样的一个错误 Uncaught TypeError: download is not a function     at HTMLAnchorElement.onclick (index.html:25) 我的html 代码为 <a href="javascript:void(0)" class="down_btn downloadButton" onclick="download()"></a>

浏览器提示Uncaught TypeError: object is not a function XXX onclick

我在做复选框选中的测试时,做了全选和反选的设置,点击后触发onclick事件在javascript里面进行处理. 刚开始一切都正常,可是后来发现javascript里面的函数不能执行了也就是onclick="chooseOther()" 点击后无效,改来改去还是无效. 后来通过浏览器的调试功能(google 按F12),点击后提示|<input type="checkbox" id="chooseOther" name="choo

Uncaught TypeError: jQuery.i18n.browserLang is not a function

/********************************************************************* * Uncaught TypeError: jQuery.i18n.browserLang is not a function * 说明: * 使用jQuery.i18n.properties.js来做语言自动转换,结果函数无效,读 * 了一下插件源代码,发现已经换掉了接口名称.功能. * * 2017-8-28 深圳 龙华樟坑村 曾剑锋 ********

JQuery $.each遍历JSON字符串报Uncaught TypeError:Cannot use &#39;in&#39; operator to search for

查看一个简单的jQuery的例子来遍历一个JavaScript数组对象. [js] view plaincopy var json = [ {"id":"1","tagName":"apple"}, {"id":"2","tagName":"orange"}, {"id":"3","tagName&

jquery each报 Uncaught TypeError: Cannot use &#39;in&#39; operator to search for错误

用$.each()来遍历后台传过来的json数据.直接遍历传过来的数据时就发生 Uncaught TypeError: Cannot use 'in' operator to search for 这个error. 原因是:因为我们后台传过来的是json数据,但我们$.each()遍历的数据是要javascript对象;所以要把它转给javascript对象.可以使用 JSON.parse() || $.parseJSON()  这个两个方法来转换. 错误代码: <script> $(docu