无法使用点表示法或索引器表示法向对象添加属性?

时间:2016-11-22 21:33:42

标签: javascript

我正在尝试将名为params的属性添加到名为url的类的名为Page的属性中。必须为属性params分配匿名函数的返回值。

该功能运行得很好。

然而,分配函数的返回值之后,当我检查属性params是否已被分配给时,我在watch窗口或者中看不到这样的属性控制台。当我尝试从params属性中读回属性url时,我得到undefined

为什么?无论我使用点表示法还是索引器表示法来为属性写入/赋值,都会发生这种情况。以下是我的代码:

var app = 
{
    ...
};

$(document).ready(function() {
    var page = new Page(app);
    page.display();
});

var Page = function(app) {

    this.url = window.location.href;
    this.app = app;

    this.url.params = (function() {

        var p = { };

        if (this.indexOf('?') < 0) return p;

        var query = this.split('?')[1];

        var pairs = query.split('&');

        if (pairs === undefined || pairs.length == 0) return p;

        for(var i = 0; i < pairs.length; i++) {
            var pair = pairs[i].trim();

            if (pair.length == 0) continue;

            if (pair.indexOf('=') < 0) {
                p[pair[0]] = '';
            }
            else {
                var prop = pair.split('=');

                p[prop[0]] = prop[1];
            }
        }

    }.bind(this.url))();

    this.display = function() {

        debugger;

        // over here, when I watch 'url', it does
        // not have a 'params' property
    };
};

4 个答案:

答案 0 :(得分:1)

将属性分配给原始字符串值不会导致错误。相反,它在内部将字符串类型提升为String对象,执行赋值,然后丢弃String对象。

这样做的原因是为原始字符串值启用String.prototype getter和方法。 (类似的考虑适用于在原始数字类型值上使用Number.prototype方法)

在你的情况下

this.url = window.location.href;

this.url设置为原始字符串值。然后,当您将url.params设置为函数时,它将在内部并有效地视为

new String(this.url).params = function () ....

用于赋值,但创建的String对象在语句执行后被丢弃。 this.url中的原始值不会获得属性 - 它不是对象数据类型,也没有属性。

答案 1 :(得分:0)

您只是忘了添加函数的return语句。修复它,你的代码将运行得很好:D

答案 2 :(得分:0)

首先,绑定语法/调用是错误的。你实际上不需要使用bind函数来做这样的事情。是否有使用bind的特定原因?我通过将window.location.href传递给url.params赋值函数来完成此工作;我还将url更改为初始化为空对象this.url = {};

我的完整工作代码:

var app = 
{
};

$(document).ready(function() {
    var page = new Page(app);
    page.display();
});

var Page = function(app) {

    //this.url = window.location.href;
    this.url = {};
    this.app = app;

    this.url.params = (function(url) {

        var p = { };

        if (url.indexOf('?') < 0) return p;

        var query = url.split('?')[1];

        var pairs = query.split('&');

        if (pairs === undefined || pairs.length == 0) return p;

        for(var i = 0; i < pairs.length; i++) {
            var pair = pairs[i].trim();

            if (pair.length == 0) continue;

            if (pair.indexOf('=') < 0) {
                p[pair[0]] = '';
            }
            else {
                var prop = pair.split('=');

                p[prop[0]] = prop[1];
            }
        }

        return p;

    })(window.location.href); //.bind(window.location.href /*this.url*/)();

    this.display = function() {

        debugger;

        console.log('display', this.url);

        // This url (http://zikro.gr/dbg/html/js-bind.html?some=1&url=2&vars=3)
        // Outputs in the console:
        // Object
        //  params: Object
        //    some: "1"
        //    url: "2"
        //    vars: "3"

    };
};

您可以在恢复调试器断点后检查调试器和控制台(使用?some=1&url=2&vars=3 url查询字符串的示例):

Object
 params: Object
   some: "1"
   url: "2"
   vars: "3"

您可以在此处查看我的工作示例:http://zikro.gr/dbg/html/js-bind.html?some=1&url=2&vars=3

修改

您的代码似乎运行良好。您只需要将this.url初始化为this.url = {};之类的对象,然后在绑定函数中返回p数组,如下所示:

var Page = function(app) {

    //this.url = window.location.href;
    this.url = {};
    this.href = window.location.href;
    this.app = app;

    this.url.params = (function(url) {

        var p = { };

        if (this.indexOf('?') < 0) return p;

        var query = this.split('?')[1];

        var pairs = query.split('&');

        if (pairs === undefined || pairs.length == 0) return p;

        for(var i = 0; i < pairs.length; i++) {
            var pair = pairs[i].trim();

            if (pair.length == 0) continue;

            if (pair.indexOf('=') < 0) {
                p[pair[0]] = '';
            }
            else {
                var prop = pair.split('=');

                p[prop[0]] = prop[1];
            }
        }

        return p;

    }.bind(this.href))();

    this.display = function() {
        debugger;
    };
};

答案 3 :(得分:0)

正如@baao在对问题的评论中所指出的那样,问题是 - 你可能不会将自定义属性添加到字符串文字中,但你可以添加到String对象。两者之间存在差异。

下面的代码片段证明了这一点。

var foo = "foo";
var bar = new String("bar");

foo.foo = "foo";
bar.bar = "bar";

alert(foo.foo);
alert(bar.bar);

很明显,修复是将url更改为对象。 @Christos Lytras也证明了这一点,并且@baao在原始问题的评论中提出了这一点。

var app = 
{
    ...
};

$(document).ready(function() {
    var page = new Page(app);
    page.display();
});

var Page = function(app) {

    this.url = { url : window.location.href };
    this.app = app;

    this.url.params = (function() {

        var p = { };

        if (this.indexOf('?') < 0) return p;

        var query = this.split('?')[1];

        var pairs = query.split('&');

        if (pairs === undefined || pairs.length == 0) return p;

        for(var i = 0; i < pairs.length; i++) {
            var pair = pairs[i].trim();

            if (pair.length == 0) continue;

            if (pair.indexOf('=') < 0) {
                p[pair[0]] = '';
            }
            else {
                var prop = pair.split('=');

                p[prop[0]] = prop[1];
            }
        }

        return p;

    }.bind(this.url.url))();

    this.url.getErrorMessage = function() {
        return this.params['error'];
    };

    this.url.getAccesToken = function() {
        return this.params['access_token'];
    };

    this.url.search = function(pattern) {
        return this.url.search(pattern);
    }

    this.display = function() {

        ...
    };
};