Function
Function构造函数可以用来创建Function对象,直接调用Function构造函数可以动态创建函数,但有安全性和与eval相同的性能问题。不同于eval的是,Function构造函数只能在全局作用域创建函数。
每个JavaScript函数实际上都是一个Function对象。
1 | (function() {}).constructor === Function; // true |
Properties
Function.prototype.callerFunction.prototype.lengthFunction.prototype.nameFunction.prototype.displayNameFunction.prototype.constructor
Methods
Function.prototype.apply()Function.prototype.bind()Function.prototype.call()Function.prototype.isGenerator()Function.prototype.toSource()Function.prototype.toString()
Object
Object.assign()Object.create()Object.defineProperty()Object.defineProperties()Object.entries()Object.entries()Object.freeze()Object.fromEntries()Object.getOwnPropertyDescriptor()Object.getOwnPropertyDescriptors()Object.prototype.hasOwnProperty()Object.prototype.isPrototypeOf()Object.prototype.propertyIsEnumerable()Object.prototype.toSource()Object.prototype.toString()Object.prototype.toLocaleString()Object.prototype.unwatch()Object.prototype.valueOf()Object.prototype.watch()
Object literal notation vs JSON
JSON的属性名必须用双引号扩起来,并且不能使用简写,如{ x }JSON的值只能是strings、numbers、arrays、true、false、null、或者另一个JSON对象- 函数不能作为
JSON的值 Date对象会被parse为stringJSON.parse()遇到计算属性(getter、setter)会报错
Object.assgin()
只复制enumerable和own的properties。在source上使用[[Get]],在target上使用[[Set]],因此会调用getters和setters方法。
不适用于包含getters的source的merge。
1 | var foo = { |
如果需要copy属性的定义,如enumerability,需要使用Object.getOwnPropertyDescriptor()和Object.defineProperty()。
String和Symbol类型的属性都会被复制。
Object.assign不接收参数null和undefined,会报错。原始类型会被包装成对象。
1 | var v1 = 'abc'; |
如果assign过程中报错,之前的改变会保留在target上:
1 | var target = Object.defineProperty({}, 'foo', { |
polyfill
1 | if (typeof Object.assign !== 'function') { |
Object.create()
创建一个新对象,并将传入的对象参数作为新对象的原型。
例子:
1 | // Shape |
继承多个对象:
1 | function MyClass() { |
使用Object.create()的propertiesObject参数:
1 | var o; |
继承自null的对象:
1 | var oco = Object.create({}); // 普通对象 |
1 | var ocn = Object.create(null); |
polyfill
1 | if (typeof Object.create !== 'function') { |
Object.defineProperty()
在一个对象上,定义一个新属性,或修改一个已存在的属性。不能重复调用,重复调用会报错。
Syntax
Object.defineProperty(obj, prop, descriptor)
默认值:
configurable: falseenumerable: falsevalue: undefinedwritable: falseget: undefinedset: undefined
当descriptor有value和writable,或者get和set之一时,被视为data descriptor。
相反的,当descriptor同时有value或writable,和get或set时,会报错。
1 | // 对 |
其他例子。
Object.defineProperties()
Syntax
Object.defineProperties(obj, props)
polyfill
1 | function defineProperties(obj, properties) { |
Object.entries()
返回给定对象的own enumerable string-keyed属性[key, value]对的数组。和for...in循环的顺序是一致的。
如果需要返回特定顺序,可以做个sort:
Object.entries(obj).sort((a, b) => b[0].localCompare(a[0]));
Syntax
Object.entries(obj)
polyfill
1 | if (!Object.entries) { |
Object.fromEntries()
Object.entries()作用相反的方法。
Object.freeze()
一个被冷冻的对象不能再修改。它的原型,即__proto__属性也不能被修改。
Syntax
Object.freeze(obj)
冷冻有元素的ArrayBufferView会报错。
1 | > Object.freeze(new Unit8Array(0)) // No elements |
Object.seal()
禁止添加新的属性,已有属性被设置为non-configurable。现有属性如果writable为true,则仍可修改。
Syntax
Object.seal(obj)
Object.preventExtensions()
不能再添加新的属性。
Object.isExtensible()
Object.isFrozen()
Object.isSealed()
Object.getOwnPropertyDescriptor()
返回own property的descriptor。
Syntax
Object.getOwnPropertyDescriptor(obj, prop)
Object.getOwnPropertyDescriptors()
应用:
浅复制
1 | Object.create( |
创建子类
1 | function SuperClass() {} |
Object.getOwnPropertyNames()
返回一个包含所有属性的数组(包括non-enumerable属性,不包括Symbol类型).
Object.getOwnPropertySymbols()
返回一个包含所有Symbol类型属性的数组。
Object.keys()
返回一个包含所有own、enumerable、string属性的数组。
polyfill
1 | // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys |
Object.values()
返回一个包含own enumerable string属性的值的数组。
Object.is()
比较两个值。
1 | Object.is('foo', 'foo'); // true |
polyfill
1 | if (!Object.is) { |
Object.getPrototypeOf()
返回内部[[Prototype]]属性的值。
Object.setPrototypeOf()
给一个对象设置原型(内部[[Prototype]]属性的值)。
注意: 更改一个对象的[[Prototype]]是一个非常慢的操作,即使现代Javascript引擎做了优化。如果对性能有要求的话,避免修改[[Prototype]],使用
Object.create()方法创建一个新对象。
polyfill
1 | // Only works in Chrome and FireFox, does not work in IE: |