为什么对象原型显示为html属性?

时间:2013-05-11 10:08:39

标签: javascript html mootools prototype

我做了这个(使用版本mootools-core-1.4.5.js)

Object.prototype.walkRecursive = function(callable, bindable) {
var p, val, retVal, _bind;

_bind = (typeof bindable === 'object') ? bindable : this;
for (p in this) {
    if (this.hasOwnProperty(p)) {
        if (!(this[p] instanceof Object)) {
            if (typeof callable === 'function')
            {
                retVal = callable.call(_bind, p, this[p]);
                if (typeof retVal !== 'undefined')
                {
                    this[p] = retVal;
                }
            }
            else {
                throw "Podaj funkcje jako drugi argument";
            }
        } else if (this[p] instanceof Object) {
            this[p].walkRecursive(callable, bindable);
        }
    }
}
return this;
};

然后

    var navigationEl = new Element('div', {
        'class' : 'wcag-navigation'
    }).inject(this._element);

当我查看Chrome开发者工具中的this._wcagButton.pausePlay HTML元素的样子时,我得到了:

strange html attribute

当我使用Mootools'的实施

 Object.implement({walkRecursive :function(callable, bindable) {....}.protect()});

为什么?请帮助,如何处理这个问题

使用示例

var data = [
{
    id: 0, 
    name: 'Template 0', 
    subComponents: [
        {id: 1, name: 'Template 1', subItems:[
            {id: 2, name: 'Template 2', subComponents:[
                {id: 3, name: 'Template 3'}
            ], 
             subItems: [
                 {id: 4, name: 'Template 4',},
                 {id: '42'}
             ]
            }
        ]}
    ]}
];

var bindMe = {
  nothing:'special'
}

data.walkRecursive(function(key,value){
if(key === 'name')
{
    return value+' '+this.nothing;
}
},bindMe)

1 个答案:

答案 0 :(得分:3)

ER。虽然can扩展Object,但仍然强烈认为这样做是不好的做法,因为在JavaScript中,所有内容都继承自该类型。要了解您不应该这样做的原因 - http://erik.eae.net/archives/2005/06/06/22.13.54/或Google extending object prototype is verboten - 有关该主题的大量答案。正如您所看到的,您添加的内容是可枚举的。

如果您只关心现代JavaScript,可以使用defineProperty将其设置为enumerable: false

为了能够在MooTools中更轻松地使用对象,曾经有一个名为Hash - http://mootools.net/docs/core125/core/Native/Hash的东西 - 现在可以在compat MooTools构建中使用 - 否则,它已被弃用对于1.4.x - 请参阅http://mootools.net/docs/core/Types/Object#Deprecated-Functions:Hash

您可以使用Object来托管方法并在对象上调用它们,这就是http://mootools.net/docs/core/Types/Object所做的。

以下是您转换的代码:http://jsfiddle.net/ZQ4Yh/3/

Object.extend({
    walkRecursive: function (object, callable, bindable) {
        var p, val, retVal, _bind;

        // this next bit is unsafe, 'object' also returned for Date or Array constructor
        _bind = (typeof bindable === 'object') ? bindable : object;
        for (p in object) {
            if (object.hasOwnProperty(p)) {
                if (!(object[p] instanceof Object)) {
                    if (typeof callable === 'function') {
                        retVal = callable.call(_bind, p, object[p]);
                        if (typeof retVal !== 'undefined') {
                            object[p] = retVal;
                        }
                    } else {
                        throw "Podaj funkcje jako drugi argument";
                    }
                    //also unsafe instanceof. 
                } else if (object[p] instanceof Object) {
                    // shouldn't you use _bind, not bindable?
                    Object.walkRecursive(object[p], callable, bindable);
                }
            }
        }
        return this;
    }
});


var data = [{
    id: 0,
    name: 'Template 0',
    subComponents: [{
        id: 1,
        name: 'Template 1',
        subItems: [{
            id: 2,
            name: 'Template 2',
            subComponents: [{
                id: 3,
                name: 'Template 3'
            }],
            subItems: [{
                id: 4,
                name: 'Template 4',
            }, {
                id: '42'
            }]
        }]
    }]
}];

var bindMe = {
    nothing: 'special'
};

Object.walkRecursive(data, function(key, value){
    if (key === 'name'){
        return value + ' ' + this.nothing;
    }
}, bindMe);

console.log(data);

// unsafe because.
console.log(new Date() instanceof Object, [] instanceof Object, function(){} instanceof Object);

// eg safer isObject
var isObject = function(what){
    return {}.toString.call(what).slice(8, -1) === 'Object';
};

console.log(isObject(new Date()), isObject([]), isObject(function(){}), isObject({}));

这包括一些不安全检查的示例以及如何以不同方式执行它们以确保正确的逻辑。

在任何情况下 - 如果您想知道 - DOM元素也返回一个元素对象,因此您可以看到您添加的内容。

有些人说如果你通过hasOwnProperty进行迭代就可以使用它,但事实并非如此。例如字典对象:

var obj = Object.create(null);
obj.name = 'template 0';

for (var k in obj){
    console.log(obj.hasOwnProperty[k]); // throws, no method hasOwnProperty
    // if you omit hasOwnProperty here, you break jslint and jshint, confusing... 
}

当然,您可以使用以下方法修复它:

var obj = Object.create(null);
obj.name = 'template 0';

var hasOwnProperty = {}.hasOwnProperty;

for (var k in obj){
    console.log(k, hasOwnProperty.call(obj, k));
}

等等 - 但它只是因为风格选择和你真正不需要的简单方便而使你的代码基础过于防御。