如何在不是对象或函数的对象实例上进行原型设计?
How to prototype on object instance that is not Object or Function?
不推荐扩展对象class,所以我尝试扩展一个对象,例如:
var obj = {'a': 1, 'b': 2, 'c': 3};
这里是object literal{'a': 1, 'b': 2, 'c': 3}
与 new Object({'a': 1, 'b': 2, 'c': 3})
相同。
我试过 obj.prototype = {d: 4}
但它把 'prototype' 设置为 属性,而不是真正的 prototype。
忘记 Object.defineProperties
!
还试过Object.create
:为什么这不起作用? ...
var ext = Object.create(obj, {'d': { value:4 }});
console.log(obj.isPrototypeOf(ext)) // => true! obj is prototype of ext
console.log(ext); // => {d: 4}
console.log(obj); // => {a: 1, b: 2, c: 3}
Console.log 说 obj.isPrototypeOf(ext) == true
那么为什么 ext
不是 {'a': 1, 'b': 2, 'c': 3, 'd': 4}
?
如何在非 Object class 或 Function 的对象实例上制作原型?
更新:作为Nicholas Tower的回答我错过了the second parameter中的可枚举应该是:{'d': { value:4, enumerable: true }}
我在 Chrome 控制台中遇到箭头下拉问题,我错过了点击查看继承值的机会。我本可以使用 assign()
到 "extend" obj。现在显示 obj = {'a': 1, 'b': 2, 'c': 3}
__proto__
{d: 4}
that is ok. From OO view that means obj
extends {d: 4}
*。在对象obj上做了一个原型。
我接受了 t.888 的回答,它帮助我了解了 console.log
如何显示对象以及扩展现有对象的正确方法。
why is ext not {'a': 1, 'b': 2, 'c': 3, 'd': 4} ?
是的,但是您没有使 d
可枚举,所以 console.log 看不到它。
const obj = {'a': 1, 'b': 2, 'c': 3};
const ext = Object.create(obj, {'d': {
value:4,
enumerable: true // <---- added this
}});
console.log('ext', ext);
for (const key in ext) {
if (ext.hasOwnProperty(key)) {
console.log('own property', key, ext[key]);
} else {
console.log('inherited property', key, ext[key]);
}
}
您可以使用 __proto__
设置原型,但它被视为遗留功能:
const obj = {a: 1, b: 2, __proto__: { c: 3 }}
console.log(obj.c) // 3
更好的方法是使用 Object.create
扩展现有对象。定义一个函数很方便
为此:
/**
* Extend an object by creating a new object with the given prototype.
*/
function extend(proto, obj) {
// Create a new object with the given prototype
const sub = Object.create(proto)
if (obj) {
// Copy the properties from 'obj' to the new object.
Object.assign(sub, obj)
}
// Return the new object.
return sub
}
// Define an object to serve as a prototype.
const proto = { a: 1, b: 2 }
// Create a new object with the given prototype.
const extended = extend(proto, { c: 3 })
console.log(extended.a, extended.b, extended.c) // 1 2 3
然而正如另一个答案指出的那样,它实际上不会显示原型属性
在 对象上:
console.log(extended) // { c: 3 }
虽然它在那里,但它不在对象本身上,而是在它的原型上:
for (let key in extended) {
console.log(key, extended[key])
}
输出:
c 3
a 1
b 2
console.log(extended.__proto__) // { a: 1, b: 2 }
Object.assign
如果您只想复制 and/or 组合对象,请使用 Object.assign
:
const first = {a: 1}
const second = {b: 2}
// Put the properties from 'second' onto 'first'.
Object.assign(first, second) // first: {a: 1, b: 2}
// Copy 'first' and 'second' to a new object.
const third = Object.assign({c: 3}, first, second) // third: {c: 3, a: 1, b: 2}
这大致相当于手动复制属性:
const first = {a: 1}
const second = {b: 2}
for (let key in second) {
if (second.hasOwnProperty(key)) {
first[key] = second[key]
}
}
console.log(first) // {a: 1, b: 2}
概括该代码,我们可以创建一个可行的 Object.assign
的近似值
在 older browsers 上 Object.assign
可能不存在:
/**
* Assign properties from object arguments [1..n] to the
* zeroth object argument.
*/
function assign() {
var first, rest
// Check of Object.assign exists and use a fallback if it doesn't.
if (typeof Object.assign === 'function') {
// Copy each object's properties to the first one.
return Object.assign.apply(null, arguments)
} else {
first = arguments[0]
rest = Array.prototype.slice.call(arguments, 1)
// Copy each object's properties to the first one.
rest.forEach((obj) => {
for (var key in obj) {
// Don't copy any of obj's prototype's properties.
if (obj.hasOwnProperty(key)) {
first[key] = obj[key]
}
}
})
return first
}
}
const obj = assign({c: 3}, {a: 1}, {b: 2})
console.log(obj) // {c: 3, a: 1, b: 2}
不推荐扩展对象class,所以我尝试扩展一个对象,例如:
var obj = {'a': 1, 'b': 2, 'c': 3};
这里是object literal{'a': 1, 'b': 2, 'c': 3}
与 new Object({'a': 1, 'b': 2, 'c': 3})
相同。
我试过 obj.prototype = {d: 4}
但它把 'prototype' 设置为 属性,而不是真正的 prototype。
忘记 Object.defineProperties
!
还试过Object.create
:为什么这不起作用? ...
var ext = Object.create(obj, {'d': { value:4 }});
console.log(obj.isPrototypeOf(ext)) // => true! obj is prototype of ext
console.log(ext); // => {d: 4}
console.log(obj); // => {a: 1, b: 2, c: 3}
Console.log 说 obj.isPrototypeOf(ext) == true
那么为什么 ext
不是 {'a': 1, 'b': 2, 'c': 3, 'd': 4}
?
如何在非 Object class 或 Function 的对象实例上制作原型?
更新:作为Nicholas Tower的回答我错过了the second parameter中的可枚举应该是:{'d': { value:4, enumerable: true }}
我在 Chrome 控制台中遇到箭头下拉问题,我错过了点击查看继承值的机会。我本可以使用 assign()
到 "extend" obj。现在显示 obj = {'a': 1, 'b': 2, 'c': 3}
__proto__
{d: 4}
that is ok. From OO view that means obj
extends {d: 4}
*。在对象obj上做了一个原型。
我接受了 t.888 的回答,它帮助我了解了 console.log
如何显示对象以及扩展现有对象的正确方法。
why is ext not {'a': 1, 'b': 2, 'c': 3, 'd': 4} ?
是的,但是您没有使 d
可枚举,所以 console.log 看不到它。
const obj = {'a': 1, 'b': 2, 'c': 3};
const ext = Object.create(obj, {'d': {
value:4,
enumerable: true // <---- added this
}});
console.log('ext', ext);
for (const key in ext) {
if (ext.hasOwnProperty(key)) {
console.log('own property', key, ext[key]);
} else {
console.log('inherited property', key, ext[key]);
}
}
您可以使用 __proto__
设置原型,但它被视为遗留功能:
const obj = {a: 1, b: 2, __proto__: { c: 3 }}
console.log(obj.c) // 3
更好的方法是使用 Object.create
扩展现有对象。定义一个函数很方便
为此:
/**
* Extend an object by creating a new object with the given prototype.
*/
function extend(proto, obj) {
// Create a new object with the given prototype
const sub = Object.create(proto)
if (obj) {
// Copy the properties from 'obj' to the new object.
Object.assign(sub, obj)
}
// Return the new object.
return sub
}
// Define an object to serve as a prototype.
const proto = { a: 1, b: 2 }
// Create a new object with the given prototype.
const extended = extend(proto, { c: 3 })
console.log(extended.a, extended.b, extended.c) // 1 2 3
然而正如另一个答案指出的那样,它实际上不会显示原型属性 在 对象上:
console.log(extended) // { c: 3 }
虽然它在那里,但它不在对象本身上,而是在它的原型上:
for (let key in extended) {
console.log(key, extended[key])
}
输出:
c 3
a 1
b 2
console.log(extended.__proto__) // { a: 1, b: 2 }
Object.assign
如果您只想复制 and/or 组合对象,请使用 Object.assign
:
const first = {a: 1}
const second = {b: 2}
// Put the properties from 'second' onto 'first'.
Object.assign(first, second) // first: {a: 1, b: 2}
// Copy 'first' and 'second' to a new object.
const third = Object.assign({c: 3}, first, second) // third: {c: 3, a: 1, b: 2}
这大致相当于手动复制属性:
const first = {a: 1}
const second = {b: 2}
for (let key in second) {
if (second.hasOwnProperty(key)) {
first[key] = second[key]
}
}
console.log(first) // {a: 1, b: 2}
概括该代码,我们可以创建一个可行的 Object.assign
的近似值
在 older browsers 上 Object.assign
可能不存在:
/**
* Assign properties from object arguments [1..n] to the
* zeroth object argument.
*/
function assign() {
var first, rest
// Check of Object.assign exists and use a fallback if it doesn't.
if (typeof Object.assign === 'function') {
// Copy each object's properties to the first one.
return Object.assign.apply(null, arguments)
} else {
first = arguments[0]
rest = Array.prototype.slice.call(arguments, 1)
// Copy each object's properties to the first one.
rest.forEach((obj) => {
for (var key in obj) {
// Don't copy any of obj's prototype's properties.
if (obj.hasOwnProperty(key)) {
first[key] = obj[key]
}
}
})
return first
}
}
const obj = assign({c: 3}, {a: 1}, {b: 2})
console.log(obj) // {c: 3, a: 1, b: 2}