Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 模块模式与原型的结合_Javascript_Design Patterns - Fatal编程技术网

Javascript 模块模式与原型的结合

Javascript 模块模式与原型的结合,javascript,design-patterns,Javascript,Design Patterns,我试图用模块模式封装一些方法。我还试图通过使用原型来避免在创建新对象时出现新的函数定义。问题是我必须实现一个构造函数,但我不知道如何实现。我的代码: // constructor function Anagram(original) { this.original = original.toLowerCase() this.sortedOriginal = this.sort(this.original) } // prototype as a module Anagram.prot

我试图用模块模式封装一些方法。我还试图通过使用原型来避免在创建新对象时出现新的函数定义。问题是我必须实现一个构造函数,但我不知道如何实现。我的代码:

 // constructor
function Anagram(original) {
  this.original = original.toLowerCase()
  this.sortedOriginal = this.sort(this.original)
}

// prototype as a module
Anagram.prototype = (function() {
  function isAnagram(word) {
    word = word.toLowerCase()
    return this.original != word && sameLetters(word)
  }
  function sameLetters(word) {
    return this.sortedOriginal === sort(word)
  }
  function sort(str) {
    return str.split('').sort().join('')
  }
  return {
    match: function(words) {
      return words.filter(isAnagram, this)
    }
  }
}())

module.exports = Anagram
运行

Anagram.new('ant').match(['tan', 'stand', 'at'])
失败于

TypeError: Object #<Object> has no method 'sort'
TypeError:对象#没有方法“sort”

我理解为什么构造函数中没有定义排序。如何修复它?

问题在于排序不是原型的属性。原型只有一个名为match的属性,要修复它,您需要对Anagram的原型进行排序。因此,在使用“match”函数返回对象文本时,该对象还需要一个“sort”函数属性

return {
   match: function(words) {
      return words.filter(isAnagram, this)
   },

   sort: function(str) {
      return str.split('').sort().join('')
   }
}
因此,每个字谜从它的原型继承两个函数,这个.sort()是有效的


但是,您的代码还有一些其他问题。您定义的函数不属于成为原型的返回对象的一部分(例如sameLetters),它们不会绑定到适当的“this”。如果您想让他们得到正确的值,他们还需要继续原型,或者您需要在调用他们时向他们传递对此的引用。

我创建了一个名为的库,它将模块模式与原型继承相结合。例如,您可以使用
augment
按如下方式实现您的
Anagram
“类”:

var augment = require("augment");

var Anagram = module.exports = augment(Object, function () {
    this.constructor = function (original) {
        this.original = original.toLowerCase();
        this.sortedOriginal = sort(this.original);
    };

    function isAnagram(word) {
        word = word.toLowerCase();
        return this.original !== word && sameLetters.call(this, word);
    }

    function sameLetters(word) {
        return this.sortedOriginal === sort(word);
    }

    function sort(str) {
        return str.split("").sort().join("");
    }

    this.match = function(words) {
        return words.filter(isAnagram, this);
    };
});
function defclass(base, body) {
    var uber = base.prototype;
    var prototype = Object.create(uber);
    var constructor = (body.call(prototype, uber), prototype.constructor);
    constructor.prototype = prototype;
    return constructor;
}
现在您可以按如下方式使用它:

new Anagram("ant").match(["tan", "stand", "at"]);
请参见演示:


编辑:如果您希望使用
deflcass
作为
augment
的替代品:

var augment = require("augment");

var Anagram = module.exports = augment(Object, function () {
    this.constructor = function (original) {
        this.original = original.toLowerCase();
        this.sortedOriginal = sort(this.original);
    };

    function isAnagram(word) {
        word = word.toLowerCase();
        return this.original !== word && sameLetters.call(this, word);
    }

    function sameLetters(word) {
        return this.sortedOriginal === sort(word);
    }

    function sort(str) {
        return str.split("").sort().join("");
    }

    this.match = function(words) {
        return words.filter(isAnagram, this);
    };
});
function defclass(base, body) {
    var uber = base.prototype;
    var prototype = Object.create(uber);
    var constructor = (body.call(prototype, uber), prototype.constructor);
    constructor.prototype = prototype;
    return constructor;
}

请参阅演示:

您的代码将无法工作,因为在
sameLetters
中调用了
sort
,而不仅仅是在构造函数中。感谢您指出
此问题。有没有一种方法可以在闭包中隐藏一个函数,并让它引用一个正确的
this
,除非显式地传递它?答案并不准确。它的值取决于调用函数的方式,因此,如果您希望拥有一个不在原型上的“私有”函数,那么您需要将“this”传递给该函数。否则,
将从调用函数的对象中推断出来。你可以这样做:
privateUtilFunction.call(this,word)
从原型上的函数,但你必须确保每当你调用
privateUtilFunction
时,你都确保设置了“this”。谢谢,有趣的解决方案,但是有没有一种方法可以在没有外部库的情况下解决我的问题?当然。您可以使用
defclass
作为
augment
的替代品。看看我最新的答案。我试着去理解defclass,我不得不承认这对我来说是一种思维扭曲。特别是行
var构造函数=(body.call(prototype,uber),prototype.constructor)