像jquery函数链一样创建动态原型

时间:2016-12-25 03:20:13

标签: javascript jquery

我尝试创建一个像jQuery一样的动态原型并能够实现链的功能,但是在没有使用new和函数内部的情况下我得到了错误,返回this对象是否正确?



    (function() {
      var peopleDynamicProto = function(name, age, state) {

        this.name = name;
        this.age = age;
        this.state = state;

        if (typeof this.printPerson !== 'function') {
          peopleDynamicProto.prototype.printPerson = function() {
            console.log(this.name + ',' + this.age + ',' + this.state);
            return this;
          };
        }

        if (!this.hasOwnProperty('gender')) {
          peopleDynamicProto.prototype.gender = 'male';
          return this;
        }
      }

      window.peopleDynamicProto = peopleDynamicProto;
      return peopleDynamicProto;

    })();

     //var person1 = new peopleDynamicProto('john', 23,'CA');
     //person1.printPerson();

    peopleDynamicProto('john', 23, 'CA').printPerson(); //got error




任何人都知道问题在哪里?

4 个答案:

答案 0 :(得分:3)

你必须使用" new"如果你想根据原型创建一个新对象。 我不确定你要做什么,以及为什么要尝试动态创建原型。我不会说100%肯定,但我不认为jQuery会这样做(加上它看起来像一个非常糟糕的做法)。 如果您尝试执行类似jQuery的操作,那么您的类可以链接并且可以链接为(new peopleDynamicProto(...)).print()peopleDynamicProto(...).print(),那么您可以执行以下操作:

function peopleDynamicProto(name) {
  if (this instanceof peopleDynamicProto) {
    /* initialize attributes here */
    this.name = name;
  } else {
    return new peopleDynamicProto(name);
  }
}

peopleDynamicProto.prototype.printPerson = function() {
   console.log( this.name );
   return this;
}

现在你应该能够以两种方式调用它:

peopleDynamicProto('john').printPerson();
(new peopleDynamicProto('john')).printPerson();

如果你不关心支持两种方式,那么你可以只返回一个对象,例如:

function peopleDynamicProto(name) {
  return {
    name: name,
    printPerson = function() {
      console.log( this.name );
      return this;
    }
  };
}

peopleDynamicProto('John').printPerson();

(还有其他方法)

答案 1 :(得分:2)

我认为你得到这样一个错误的原因是因为你在这里返回的是一个函数而不是一个对象,但是你试图访问一个对象的属性。

例如, 如果你写为:

**

var myFun = function(){
 this.message = "TEST";
}

**

你无法访问myFUN.message,因为 myFun是一个函数而不是这个函数构造函数的对象

要访问其属性,您需要执行类似的操作 (new myFun())。message ;

同样在你的情况下你返回的是“peopleDynamicProto”,它只是一个函数,不是这个函数构造函数的对象

要访问方法printPerson(作为成员),您需要创建peopleDynamicProto的实例并访问其成员

答案 2 :(得分:1)

我猜你错过了new运营商 - see this for reference

  

new运算符创建用户定义的对象类型或的实例   其中一个具有构造函数的内置对象类型。

见下面的演示:

(function() {
  var peopleDynamicProto = function(name, age, state) {

    this.name = name;
    this.age = age;
    this.state = state;

    if (typeof this.printPerson !== 'function') {
      peopleDynamicProto.prototype.printPerson = function() {
        console.log(this.name + ',' + this.age + ',' + this.state);
        return this;
      };
    }

    if (!this.hasOwnProperty('gender')) {
      peopleDynamicProto.prototype.gender = 'male';
      return this;
    }
  }

  window.peopleDynamicProto = peopleDynamicProto;
  return peopleDynamicProto;

})();

var person1 = new peopleDynamicProto('john', 23,'CA');
person1.printPerson();

new peopleDynamicProto('john', 23, 'CA').printPerson(); //got error

答案 3 :(得分:1)

你无法在构造函数内创建原型。看到这个解释 defining-prototype-methods-inside-the-constructor

使用此关键字而不是原型:

(function(){
    var peopleDynamicProto = function(name, age, state){

    this.name   = name;
    this.age    = age;
    this.state  = state;

    this.printPerson = function(){
            console.log( this.name + ',' + this.age + ',' + this.state );
            return this;

    }
    if( !this.hasOwnProperty('gender') ){
        peopleDynamicProto.prototype.gender = 'male';
        return this;
    } 
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();

peopleDynamicProto('john', 23,'CA').printPerson();

或使用原型外部构造函数(这是更好的,因为每次创建对象时都不会重新创建函数对象)

(function(){
 var peopleDynamicProto = function(name, age, state){

    this.name   = name;
    this.age    = age;
    this.state  = state;

    if( !this.hasOwnProperty('gender') ){
        peopleDynamicProto.prototype.gender = 'male';
        return this;
    } 
}
if( typeof this.printPerson !== 'function' ){
        peopleDynamicProto.prototype.printPerson = function(){
            console.log( this.name + ',' + this.age + ',' + this.state );
            return this;
        };
    }
 window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();