signal은 es6 메소드입니다. 할당()은 es6 객체 객체의 새로운 메소드입니다. "Object.sign()" 메소드는 객체를 병합하는 데 사용됩니다. 이 메소드는 소스 객체의 열거 가능한 모든 속성을 이 메소드의 첫 번째 객체에 복사할 수 있습니다. 매개변수는 대상 개체이고 후속 매개변수는 모두 소스 개체입니다.
이 튜토리얼의 운영 환경: Windows 7 시스템, ECMAScript 버전 6, Dell G3 컴퓨터.
Assign은 es6 메소드입니다.
Object.sign()은 es6의 새로운 메소드로, 객체를 병합하고 소스 객체(source)의 열거 가능한 모든 속성을 대상 객체(target)에 복사하는 데 사용됩니다.
const target = { a: 1, b: 2 } const source = { b: 4, c: 5 } const returnedTarget = Object.assign(target, source) target // { a: 1, b: 4, c: 5 } returnedTarget // { a: 1, b: 4, c: 5 }
Object.asse
메소드의 첫 번째 매개변수는 대상 객체이고, 그 다음 매개변수는 모두 소스 객체입니다. Object.assign
方法的第一个参数是目标对象,后面的参数都是源对象。
注意:如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
const target = { a: 1, b: 1 } const source1 = { b: 2, c: 2 } const source2 = { c: 3 } Object.assign(target, source1, source2) target // {a:1, b:2, c:3}
如果只有一个参数,Object.assign
会直接返回该参数。
const obj = {a: 1} Object.assign(obj) // {a: 1} Object.assign(obj) === obj // true
如果该参数不是对象,则会先转成对象,然后返回。
typeof Object.assign(2) // "object"
由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
Object.assign(undefined) // 报错 Object.assign(null) // 报错
如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。
let obj = {a: 1} Object.assign(obj, undefined) === obj // true Object.assign(obj, null) === obj // true
其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。
const v1 = 'abc' const v2 = true const v3 = 10 const obj = Object.assign({}, v1, v2, v3) obj // { "0": "a", "1": "b", "2": "c" }
上面代码中,v1、v2、v3分别是字符串、布尔值和数值,结果只有字符串合入目标对象(以字符数组的形式),数值和布尔值都会被忽略。这是因为只有字符串的包装对象,会产生可枚举属性。
Object.assign(true) // {[[PrimitiveValue]]: true} Object.assign(10) // {[[PrimitiveValue]]: 10} Object.assign('abc') // {0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"}
上面代码中,布尔值、数值、字符串分别转成对应的包装对象,可以看到它们的原始值都在包装对象的内部属性 [[PrimitiveValue]]
上面,这个属性是不会被Object.assign
拷贝的。只有字符串的包装对象,会产生可枚举的实义属性,那些属性则会被拷贝。
Object.assign
拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性),也不拷贝不可枚举的属性(enumerable: false
)。
Object.assign({b: 'c'}, Object.defineProperty({}, 'invisible', { enumerable: false, value: 'hello' }) ) // { b: 'c' }
上面代码中,Object.assign
要拷贝的对象只有一个不可枚举属性invisible
,这个属性并没有被拷贝进去。
属性名为 Symbol
值的属性,也会被Object.assign
拷贝。
Object.assign({ a: 'b' }, { [Symbol('c')]: 'd' }) // { a: 'b', Symbol(c): 'd' }
注意点
(1)浅拷贝
Object.assign
方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
const obj1 = {a: {b: 1}} const obj2 = Object.assign({}, obj1) obj1.a.b = 2 obj2.a.b // 2
上面代码中,源对象obj1
的a
属性的值是一个对象,Object.assign
拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。
(2)同名属性的替换
对于这种嵌套的对象,一旦遇到同名属性,Object.assign
的处理方法是替换,而不是添加。
const target = { a: { b: 'c', d: 'e' } } const source = { a: { b: 'hello' } } Object.assign(target, source) // { a: { b: 'hello' } }
上面代码中,target
对象的a
属性被source
对象的a
属性整个替换掉了,而不会得到{ a: { b: 'hello', d: 'e' } }
的结果。这通常不是开发者想要的,需要特别小心。
一些函数库提供 Object.assign
的定制版本(比如 Lodash
的_.defaultsDeep
方法),可以得到深拷贝的合并。
(3)数组的处理Object.assign
可以用来处理数组,但是会把数组视为对象。
Object.assign([1, 2, 3], [4, 5]) // [4, 5, 3]
上面代码中,Object.assign
把数组视为属性名为 0、1、2
的对象,因此源数组的 0
号属性4
覆盖了目标数组的 0
号属性1
。
(4)取值函数的处理
Object.assign
只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。
const source = { get foo() { return 1 } } const target = {} Object.assign(target, source) // { foo: 1 }
上面代码中, source
对象的foo
属性是一个取值函数,Object.assign
不会复制这个取值函数,只会拿到值以后,将这个值复制过去。
Object.assign的用法
Object.assign
class Point { constructor(x, y) { Object.assign(this, {x, y}) } }🎜매개변수가 하나만 있는 경우
Object.sign
은 매개변수를 직접 반환합니다. 🎜Object.assign(SomeClass.prototype, { someMethod(arg1, arg2) { ··· }, anotherMethod() { ··· } }) // 等同于下面的写法 SomeClass.prototype.someMethod = function (arg1, arg2) { ··· } SomeClass.prototype.anotherMethod = function () { ··· }🎜매개변수가 객체가 아닌 경우 먼저 객체로 변환된 후 반환됩니다. 🎜
function clone(origin) { return Object.assign({}, origin) }🎜undefine과 null은 객체로 변환할 수 없기 때문에 매개변수로 사용하면 오류가 발생합니다. 🎜
function clone(origin) { let originProto = Object.getPrototypeOf(origin) return Object.assign(Object.create(originProto), origin) }🎜비객체 매개변수가 원본 객체의 위치에 나타나는 경우(즉, 첫 번째 매개변수가 아닌 경우) 처리 규칙이 다릅니다. 먼저, 이러한 매개변수는 객체로 변환됩니다. 객체로 변환할 수 없으면 건너뜁니다. 즉, 첫 번째 매개변수에 정의되지 않음과 null이 없으면 오류가 보고되지 않습니다. 🎜
const merge = (target, ...sources) => Object.assign(target, ...sources)🎜다른 유형의 값(예: 숫자 값, 문자열 및 부울 값)은 첫 번째 매개변수에 포함되지 않으며 오류가 보고되지 않습니다. 다만, 문자열이 배열 형태로 대상 객체에 복사된다는 점을 제외하면 다른 값은 아무런 영향을 미치지 않습니다. 🎜
const merge = (...sources) => Object.assign({}, ...sources)🎜위 코드에서 v1, v2, v3은 각각 문자열, 부울값, 숫자값이므로 결과적으로 문자열만 (문자배열 형태로) 대상객체에 결합되며, 숫자 값과 부울 값은 무시됩니다. 이는 문자열 래퍼 개체만 열거 가능한 속성을 생성하기 때문입니다. 🎜
const DEFAULTS = { logLevel: 0, outputFormat: 'html' } function processContent(options) { options = Object.assign({}, DEFAULTS, options) console.log(options) // ... }🎜위 코드에서는 부울 값, 숫자 값, 문자열이 각각 해당 패키징 개체로 변환됩니다. 원래 값이 패키징 개체
[[PrimitiveValue]의 내부 속성보다 위에 있음을 알 수 있습니다. ]]
. 이 속성은 Object.sign
에 의해 복사되지 않습니다. 문자열 래퍼 개체만 열거 가능한 리터럴 속성을 생성하고 해당 속성은 복사됩니다. Object.sign
복사되는 속성은 소스 객체의 자체 속성만 복사되며(상속된 속성은 복사되지 않음), 열거할 수 없는 속성( 열거 가능: false)
). 🎜const DEFAULTS = { url: { host: 'example.com', port: 7070 }, } processContent({ url: {port: 8000} }) // { // url: {port: 8000} // }🎜위 코드에서
Object.sign
으로 복사할 객체에는 열거 불가능한 invisible
속성이 하나만 있고, 이 속성은 복사되지 않습니다. 🎜🎜속성 이름이 Symbol
값인 속성도 Object.sign
에 의해 복사됩니다. 🎜rrreee🎜🎜Notes🎜🎜🎜🎜 (1) 얕은 복사🎜🎜🎜Object.sign
메소드는 얕은 복사를 구현하지 않습니다. 딥 카피. 즉, 소스 개체의 특정 속성 값이 개체인 경우 대상 개체의 복사본은 이 개체에 대한 참조를 얻습니다. 🎜rrreee🎜위 코드에서 소스 객체 obj1
의 a
속성 값이 객체이고, Object.asset에 의해 복사된 내용입니다. code>가 이 개체입니다. 이 개체에 대한 모든 변경 사항은 대상 개체에 반영됩니다. 🎜🎜🎜(2) 동일한 이름의 속성 대체🎜🎜🎜이러한 중첩 객체의 경우 동일한 이름의 속성이 발견되면 <code>Object.sign
의 처리 방법은 대체하는 것입니다. , 추가하지 마세요. 🎜rrreee🎜위 코드에서 target
객체의 a
속성은 sourcea
속성으로 완전히 대체되었습니다. /code> 객체. { a: { b: 'hello', d: 'e' } }
의 결과를 얻는 대신. 이는 일반적으로 개발자가 원하는 것이 아니며 특별한 주의가 필요합니다. 🎜🎜일부 함수 라이브러리는 전체 복사를 얻을 수 있는 Object.sign
(예: Lodash
의 _.defaultsDeep
메서드)의 사용자 정의 버전을 제공합니다. 병합. 🎜🎜(3) 배열 처리 Object.sign
을 사용하여 배열을 처리할 수 있지만 배열은 객체로 처리됩니다. 🎜rrreee🎜위 코드에서 Object.sign
은 배열을 속성 이름이 0, 1, 2
인 객체로 처리하므로 소스 배열은 0 숫자 속성 <code>4
는 대상 배열의 0
숫자 속성 1
을 덮어씁니다. 🎜🎜🎜(4) 값 함수 처리🎜🎜🎜Object.sign
은 값 복사만 가능합니다. 복사할 값이 값 함수인 경우 평가한 후 복사됩니다. 🎜rrreee🎜위 코드에서 source
객체의 foo
속성은 값 함수이고, Object.sign
은 이 값을 복사하지 않습니다. 함수입니다. 값을 가져온 후에만 이 값이 복사됩니다. 🎜🎜🎜Object.sign 사용🎜🎜🎜Object.sign
메서드에는 다양한 용도가 있습니다. 🎜(1)为对象添加属性
class Point { constructor(x, y) { Object.assign(this, {x, y}) } }
上面方法通过Object.assign
方法,将x
属性和y
属性添加到Point
类的对象实例。
(2)为对象添加方法
Object.assign(SomeClass.prototype, { someMethod(arg1, arg2) { ··· }, anotherMethod() { ··· } }) // 等同于下面的写法 SomeClass.prototype.someMethod = function (arg1, arg2) { ··· } SomeClass.prototype.anotherMethod = function () { ··· }
上面代码使用了对象属性的简洁表示法,直接将两个函数放在大括号中,再使用assign
方法添加到SomeClass.prototype
之中。
(3)克隆对象
function clone(origin) { return Object.assign({}, origin) }
上面代码将原始对象拷贝到一个空对象,就得到了原始对象的克隆。
不过,采用这种方法克隆,只能克隆原始对象自身的值,不能克隆它继承的值。如果想要保持继承链,可以采用下面的代码。
function clone(origin) { let originProto = Object.getPrototypeOf(origin) return Object.assign(Object.create(originProto), origin) }
(4)合并多个对象
将多个对象合并到某个对象。
const merge = (target, ...sources) => Object.assign(target, ...sources)
如果希望合并后返回一个新对象,可以改写上面函数,对一个空对象合并。
const merge = (...sources) => Object.assign({}, ...sources)
(5)为属性指定默认值
const DEFAULTS = { logLevel: 0, outputFormat: 'html' } function processContent(options) { options = Object.assign({}, DEFAULTS, options) console.log(options) // ... }
上面代码中,DEFAULTS
对象是默认值,options
对象是用户提供的参数。Object.assign
方法将DEFAULTS
和options
合并成一个新对象,如果两者有同名属性,则option
的属性值会覆盖DEFAULTS
的属性值。
注意:由于存在浅拷贝的问题,DEFAULTS
对象和options
对象的所有属性的值,最好都是简单类型,不要指向另一个对象。否则,DEFAULTS
对象的该属性很可能不起作用。
const DEFAULTS = { url: { host: 'example.com', port: 7070 }, } processContent({ url: {port: 8000} }) // { // url: {port: 8000} // }
上面代码的原意是将 url.port
改成 8000
,url.host
不变。实际结果却是options.url
覆盖掉DEFAULTS.url
,所以url.host
就不存在了。
【相关推荐:javascript视频教程、web前端】
위 내용은 es6 메소드를 할당합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!