可以返回值并充当对象的函数

时间:2014-12-31 18:00:36

标签: javascript

这个问题似乎很难形成,所以我只提供一个我想要完成的例子::

function test(word) {
    return word
}

function replaceWord(word) {
    return word
}
test('Hello').replaceWord('World')

所以我希望能够返回“Hello”,如果我愿意,可以链接replaceWord函数。

与jquery如何处理

之类的东西相比
$('#element').something('doit').somethingElse();

我觉得我在

的正确轨道上
var test = function (word) {
    return word;
}
test.prototype = {
    replaceWord: function (word) {
        return word;
    }
}

但是因为我正在返回字符串,所以链不起作用。我应该这样做的正确方法是能够拥有一个可以返回值[test('Hello')]的函数,还可以作为一个对象来修改函数返回的值/ s的数据[test('Hello')。replaceWord('World')]将值保留在'World'?

5 个答案:

答案 0 :(得分:4)

不可能返回以这种方式链接的普通值(没有包装或额外属性)。对于字符串尤其如此,因为它们是原语并且不能拥有自己的属性。 jQuery通过使所有内容成为包装器来实现这一目标:

function test(word) {
    this.word = word;
}

test.prototype.next = function (word) {
    this.word = word;
    return this;
};

// or, if next() shouldn’t modify its context

test.prototype.next = function (word) {
    return new test(word);
};

然后

test.prototype.get = function () {
    return this.word;
};

打开包装器。你可以用它作为:

new test('Hello').next('World').get();

删除像jQuery一样的new

function test(word) {
    if (!(this instanceof test)) {
        return new test(word);
    }

    this.word = word;
}

答案 1 :(得分:2)

一些想法:

  • 将方法添加到返回值继承的对象。

    function test(word) {
        return word;
    }
    String.prototype.replaceWord = function(word) {
        return word;
    }
    test('Hello'); // 'Hello'
    test('Hello').replaceWord('World'); // 'World'
    

    但是,不建议修改您未创建的对象(String.prototype)。

    此外,如果test返回undefinednull,它将无法运作。

  • 对返回值继承的对象进行子类化。

    function myString(str) {
        this._value = str;
    }
    myString.prototype = Object.create(String.prototype);
    myString.prototype.constructor = myString;
    myString.prototype.toString = myString.prototype.valueOf = function() {
        return this._value;
    };
    function test(word) {
        return new myString(word);
    }
    myString.prototype.replaceWord = function(word) {
        return word;
    }
    test('Hello') + ''; // 'Hello'
    test('Hello').replaceWord('World'); // 'World'
    

    此处test无法返回文字字符串,但返回的行为接近字符串对象。

    请注意,这可能不适用于某些浏览器。

  • 使用包装器,并在最后检索值

    function Chain(value) {
        this.value = value;
    }
    Chain.prototype.replaceWord = function(word) {
        this.value = word;
        return this;
    }
    function test(word) {
        return new Chain(word);
    }
    test('Hello').value; // "Hello"
    test('Hello').replaceWord('World').value; // "World"
    

    在这种情况下,函数不会直接返回值(您必须撤回它),但它是最灵活的。

答案 2 :(得分:1)

不完全确定你最终想要完成什么,但也许这可能会有所帮助:

Object.prototype.next = function(word) { return word; }

test('Hello') // "Hello"
test('Hello').next('World') // "World"

答案 3 :(得分:1)

像jQuery这样的系统的技巧是第一个函数构建某个特定类型的对象并返回它。该对象的原型是随后的"链#34;方法位于。所有这些方法与该方案合作并返回相同的对象(或该对象的转换版本)非常重要。这就是为什么jQuery方法的基本模式(粗略地):

$.fn.someMethod = function() {
  return this.each(function() {
    // do something
  });
};

里面的.each()方法本身就是一个合作的jQuery方法,所以它返回this(与jQuery 回调不同,它是对jQuery对象的引用而不是一个DOM元素)。因此,通过尽职地返回jQuery对象,链可以继续。

请注意,一些jQuery方法本质上不遵循该规则。一个熟悉的例子是.val(),没有参数调用。该函数返回"值" jQuery对象列表中第一个DOM元素的属性,因为它是一个字符串(或undefined),你不能在那之后链接。

你究竟如何构建一个类似的系统在很大程度上取决于你自己的需求和你自己的设计偏好,但这就是这个想法:一类具有合作方法的对象使方法链工作。< / p>

关于如何让可链接方法直接用于字符串值的问题,答案是,如果您不愿意修改字符串原型,则不能这样做。这是jQuery面临的类似情况,每个人都使用该库必须习惯:jQuery对象一个DOM元素;它是一个包装器。要显式获取包装的DOM元素,必须将其解包。

答案 4 :(得分:0)

返回一个定义了.toString方法的对象,而不是直接返回一个字符串。

function test(word) {
    return {
        word,
        replaceWord(word) {
            this.word = word;
            return this;
        },
        toString() {
            return this.word;
        }
    }
}

结果值是一个对象,但在大多数地方可以用作字符串,或者在其他情况下可以显式转换:

// cases where string must be explicit
var str = String(test("Hello").replace("World"));

// other cases in which string cast is implicit
var str = `message: ${test("Hello").replace("World")}`;
var str = "message: " + test("Hello").replace("World");

如果您正在使用数字数据,valueOf可能更合适,而不是toString(或者在奇数情况下都可能)。实施valueOf后,您可以执行以下操作:

var num = 3 + test(32).replaceNumber(16);