如何在JS中将原型附加到Object Literals



我正在努力理解JavaScripts原型的本质,并试图在不使用类构造函数的情况下创建对象继承。

如果它们都是三个对象文字,我如何将来自Animals的原型链连接到Cat和Dog?

此外,是否有一种方法可以创建Object.create并以文字形式添加更多属性(如myCat)。

我添加了下面的代码&粘贴垃圾箱http://jsbin.com/eqigox/edit#javascript

var Animal = {
    name        : null,
    hairColor   : null,
    legs        : 4,
    getName : function() {
        return this.name;
    },
    getColor : function() {
        console.log("The hair color is " + this.hairColor);
    }
};
/* Somehow Dog extends Animal */
var Dog = {
    bark : function() {
        console.log("Woof! My name is ");
    }
};
/* Somehow Cat Extends Animal */
var Cat = {
    getName : function() {
        return this.name;
    },
    meow : function() {
        console.log("Meow! My name is " + this.name);
    }
};

/* myDog extends Dog */
var myDog = Object.create(Dog);
/* Adding in with dot notation */
myDog.name = "Remi";
myDog.hairColor = "Brown";
myDog.fetch = function() {
    console.log("He runs and brings back it back");
};

/* This would be nice to add properties in litteral form */
var myCat = Object.create(Cat, {
    name        : "Fluffy",
    hairColor   : "white",
    legs : 3, //bad accident!
    chaseBall : function(){
        console.log("It chases a ball");
    }
});
myDog.getColor();

您可以使用Object.create将定义的对象用作原型。例如:

var Dog = Object.create(Animal, {
    bark : {
        value: function() {
            console.log("Woof! My name is " + this.name);
        }
    }
});

现在您可以创建一个新的Dog对象:

var myDog = Object.create(Dog);
myDog.bark();  // 'Woof! My name is null'
myDog.getColor();  // 'The hair color is null'

示例:http://jsfiddle.net/5Q3W7/1/

或者,如果您在没有Object.create的情况下工作,您可以使用构造函数:

function Animal() {
    this.name = null;
    this.hairColor = null;
    this.legs = 4;
};
Animal.prototype = {
    getName : function() {
        return this.name;
    },
    getColor : function() {
        console.log("The hair color is " + this.hairColor);
    }
}
function Dog() {
}
Dog.prototype = new Animal;
Dog.prototype.bark = function() {
    console.log("Woof! My name is " + this.name);
};

示例:http://jsfiddle.net/5Q3W7/2/

有关Object.create的详细信息:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/create/

有关构件和原型链的详细信息:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor

https://developer.mozilla.org/en/JavaScript/Guide/Inheritance_and_the_prototype_chain

编辑:完全忽略了Object.create@jMerlinN的答案更合适,除非您需要更广泛的向后兼容性。


AnimalCatDog确实共享Object.prototype,因为它们是Object的实例,但这不是您想要放置方法的地方。

您可以使用extend函数模拟继承:

var Dog = {
    bark : function() {
        console.log("Woof! My name is ")
    }
}
jQuery.extend(Dog, Animal)

这可能是下划线的_.extend或您自己的扩展函数,它只是复制它的属性:

function extend(obj, source){
    for (var prop in source) {
        obj[prop] = source[prop]
    }
} 

但是要小心引用:字符串、数字、布尔值等"基元"值将被复制,而对象、函数和数组将被引用:

var Animal = {
    tags: [1,2,3]
}
var Dog = {
    //...
}
_.extend(Dog, Animal)
Dog.tags.push(4)
Dog.tags // [1,2,3,4]
Animal.tags // [1,2,3,4] oh no!

没有理由经历这种情况,它容易出错,内存效率较低;只需使用构造函数:)

使用ES2015及更高版本,您可以使用文字__proto__作为属性名称,在对象文字中设置原型权限:

const myProto = {
  propertyExists: function(name) {
    return name in this;
  },
};
const myNumbers = {
  __proto__: myProto,
  array: [1, 6, 7],
};
myNumbers.propertyExists('array'); // => true
myNumbers.propertyExists('collection'); // => false

这是一个很好的帖子,我从哪里得到了这个例子。

最新更新