>웹 프론트엔드 >프런트엔드 Q&A >es6 메소드를 할당합니까?

es6 메소드를 할당합니까?

青灯夜游
青灯夜游원래의
2022-03-23 14:52:261953검색

signal은 es6 메소드입니다. 할당()은 es6 객체 객체의 새로운 메소드입니다. "Object.sign()" 메소드는 객체를 병합하는 데 사용됩니다. 이 메소드는 소스 객체의 열거 가능한 모든 속성을 이 메소드의 첫 번째 객체에 복사할 수 있습니다. 매개변수는 대상 개체이고 후속 매개변수는 모두 소스 개체입니다.

es6 메소드를 할당합니까?

이 튜토리얼의 운영 환경: 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

上面代码中,源对象obj1a属性的值是一个对象,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🎜위 코드에서 소스 객체 obj1a 속성 값이 객체이고, 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: &#39;html&#39;
}

function processContent(options) {
  options = Object.assign({}, DEFAULTS, options)
  console.log(options)
  // ...
}

上面代码中,DEFAULTS对象是默认值,options对象是用户提供的参数。Object.assign方法将DEFAULTSoptions合并成一个新对象,如果两者有同名属性,则option的属性值会覆盖DEFAULTS的属性值。

注意:由于存在浅拷贝的问题,DEFAULTS对象和options对象的所有属性的值,最好都是简单类型,不要指向另一个对象。否则,DEFAULTS对象的该属性很可能不起作用。

const DEFAULTS = {
  url: {
    host: &#39;example.com&#39;,
    port: 7070
  },
}

processContent({ url: {port: 8000} })
// {
//   url: {port: 8000}
// }

上面代码的原意是将 url.port改成 8000url.host不变。实际结果却是options.url覆盖掉DEFAULTS.url,所以url.host就不存在了。

【相关推荐:javascript视频教程web前端

위 내용은 es6 메소드를 할당합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.