序文
最近vue3のメソッドのソースコードに触れました。オブジェクトメソッドがたくさん使われています。メソッドを見ながら理解しながら勉強したいです。知識のポイントを理解して、もっと感動できるようにしたいです。将来もう一度読んでください。このように追加・削除・修正しながら学習すると考えると暗記にも便利です。以下は、vue3 ソース コードで使用する必要があるオブジェクト メソッドの一部です。
JavaScript では、ほとんどすべてのオブジェクトがObject
型のインスタンスであり、それらはすべて からObject.prototype
プロパティとメソッドを継承します。ただし、ほとんどのプロパティはシャドウされるかオーバーライドされ、Object
意図的に作成することもできます。ただし、このオブジェクトは「実際のオブジェクト」ではありません。
オブジェクトの初期化(インクリメント)
new Object()
オブジェクトは、 などのメソッド、Object.create()
またはリテラル タグ (初期化タグ) を使用して初期化できます。
let emptyObject = new Object() // {}
let emptyObject = new Object(undefined) // {}
let emptyObject = new Object(null) // {}
const valueObject1 = new Object({
"name":"沐阳vae"})
console.log(valueObject1) //{name: '沐阳vae'}
const valueObject2 = new Object()
valueObject.name = "沐阳"
console.log(valueObject2) // {name: '沐阳'}
-
静态方法
1,オブジェクトの割り当て
構文: 、オブジェクト値が null または未定義の場合、エラーはスローされ
Object.assign(target, ...sources)
ません。sources
const target = { a: 1, b: 2 }; const source = { b: 4, c: 5 }; const returnTarget = Object.assign(target, source); console.log(target) // {a: 1, b: 4, c: 5} console.log(returnTarget) // {a: 1, b: 4, c: 5} console.log(source) //{ b: 4, c: 5 }
Object.assign() は、1 つ以上のオブジェクトをコピーして新しいオブジェクトを作成します。
Object.assign()
コピーによって作成されたオブジェクトは浅いコピーであり、プロパティ値のみがコピーされます。ソース オブジェクトがオブジェクトへの参照である場合、その参照値のみがコピーされます。let obj = { a: 1, b: { c: 0}} let newObj = Object.assign({ }, obj) console.log(newObj) // {a: 1, b: { c: 0}} ,浅拷贝,复制的是引用值,a复制的是1,b复制的就是引用地址了。 obj.a = 3 console.log(obj) // {a: 3, b: { c: 0}} console.log(newObj) // {a: 1, b: { c: 0}} // 后面在加上这里obj.b.c = 2,改变之后,整个引用地址里面的属性值也被改变了 obj.b.c = 2 console.log(obj) // {a: 3, b: { c: 2}} console.log(newObj) // {a: 1, b: { c: 2}} // 使用JSON.parse(JSON.stringify())进行深拷贝 let deepObj = JSON.parse(JSON.stringify(obj)) obj.a = 4 obj.b.c = 4 console.log(JSON.stringify(obj3)) // {"a":3,"b":{"c":2}} console.log(obj) // {"a":4,"b":{"c":4}}
原型链上
属性と不可枚举
属性はコピーできませんconst obj = Object.create({ foo: 1 }, { // foo 是对象原型链上的属性. notEnum: { value: 2 //没有设置enumerable,不可枚举. }, canEnum: { value: 3, enumerable: true // enumerable设置是否可以枚举. } }); const copy = Object.assign({}, obj); console.log(copy); // { canEnum: 3 }
2,オブジェクト.作成
構文:
Object.create(proto)
またはObject.create(proto, propertiesObject)
。
Object.create()
メソッドは、既存のオブジェクトを新しく作成されたオブジェクトのプロトタイプとして使用して、新しいオブジェクトを作成するために使用されます。const person = { name: 'person', printIntroduction: function() { console.log('this':this) console.log(`this指向新创建的对象${this.name}`); } } console.log(person.printIntroduction()) //this: {name: 'person', printIntroduction: ƒ} //this指向新创建的对象person const mine = Object.create(person) console.log(person.printIntroduction()) // this: {} // this指向新创建的对象person,新创建的对像上没有name属性时,回在原来的对象是取用,但是此时的this指向新创建的对象 mine.name = 'mine' console.log(mine.printIntroduction() // this: {name: 'mine'} , //this指向新创建的对象mine
例外:
proto
引数が null であるか、または基本类型包装对象
プリミティブ型以外の对象
ラッパー オブジェクトです。と を除くすべてのプリミティブ型に
null
は、undefined
対応するラッパー オブジェクトがあります。名前 説明する 弦 文字列プリミティブ型 番号 数値プリミティブ型 BigInt 大きな整数プリミティブ型 ブール値 ブールプリミティブ型 シンボル リテラルのプリミティブ型 によってプロトタイプ化されたオブジェクトは、 からオブジェクト メソッドを継承して
null
いないため、null プロトタイプ化されたオブジェクトを使用すると、予期しない動作をします。また、メソッドが不足しているため、デバッグが非常に困難になることがよくあります。Object.prototype
Object.prototype.toString()
const normalObj = { }; // 普通对象 const nullProtoObj = Object.create(null) // null作为自己的原型 console.log(normalObj) // {} console.log(nullProtoObj) // {} console.log("" + normalObj) // [object Object] console.log("" + nullProtoObj) // 报错 alert(normalObj); // 展示 [object Object] alert(nullProtoObj) // 报错 normalObj.valueOf() // shows {} nullProtoObj.valueOf() // 报错 normalObj.hasOwnProperty("p") // 展示 "false" nullProtoObj.hasOwnProperty("p") //报错 normalObj.constructor // 出现 "Object() { [native code] }" nullProtoObj.constructor // 出现"undefined"
次のように、 null でプロトタイプ化されたオブジェクトのメソッドを追加できます
toString
。nullProtoObj.toString = Object.prototype.toString; // console.log(nullProtoObj.toString()); // 展示 "[object Object]" console.log("nullProtoObj is: " + nullProtoObj); // 展示 "nullProtoObj is: [object Object]"
実際には、
null
でmap
代わりとして使用されることがよくあります。Object.prototype
プロトタイプ独自のプロパティが存在するとエラーが発生するためconst ages = { '张三': 18, '李四': 27 }; function hasPerson(name) { return name in ages; } function getAge(name) { return ages[name]; } hasPerson('李四') //true getAge('李四') // 27 hasPerson("hasOwnProperty") // true getAge("toString") // ƒ toString() { [native code] }
null プロトタイプ化されたオブジェクトを使用すると、この潜在的な問題が排除され、
hasPerson
および関数getAge
に複雑なロジックが導入されなくなります。const ages = Object.create(null, { '张三': { value: 18, enumerable: true }, '李四': { value: 27, enumerable: true }, }); function hasPerson(name) { return name in ages; } function getAge(name) { return ages[name]; } hasPerson('李四') //true getAge('李四') // 27 hasPerson("hasOwnProperty") // false getAge("toString") // undefined
Object.prototype
プロトタイプ メソッドを継承しないオブジェクトも、プロトタイプ汚染攻撃を防ぐことができます。悪意のあるスクリプトObject.prototype
によってプロパティが追加された場合、プログラム内のすべてのオブジェクトがこのプロパティにアクセスできるようになりますが、null でプロトタイプ化されたオブジェクトは影響を受けません。
オブジェクトプロパティの削除(削除)
オブジェクト自体には、独自のプロパティを削除するメソッドがありません (Map ではMap.prototype.delete()
独自のプロパティを削除できます)。オブジェクトのプロパティを削除するには、次を使用する必要があります。delete 操作符
- 削除 マッププロトタイプの削除
// 创建Map实例
const willDeleteMap = new Map()
// 对willDeleteMap对象设置属性和值
willDeleteMap.set('name', 'value')
// delete删除name属性,删除成功返回true
console.log(willDeleteMap.delete('name')) // true
// has查询对象里面是否还有名为name的属性,没有,结果返回false
console.log(willDeleteMap.has('name')) // false
- 削除演算子
// 字面量创建对象
const willDeleteMap = {
firstname: '沐',
lastname: '阳'
}
// 删除成功返回true
delete willDeleteMap.firstname
console.log(willDeleteMap) // {lastname: '阳'}
console.log(willDeleteMap.firstname)// undefined
オブジェクトを比較する
文法:Object.is(value1, value2)
Object.is()
、2つの値が同じ値であるかどうかを判断するメソッド。Object.is
どちらの側にも値を強制しません。
// Case 1
Object.is(25, 25); // true
Object.is('foo', 'foo'); // true
Object.is('foo', 'bar'); // false
Object.is(null, null); // true
Object.is(undefined, undefined); // true
Object.is(window, window); // true
Object.is([], []); // false
var foo = {
a: 1 };
var bar = {
a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false
// Case 2: Signed zero
Object.is(0, -0); // false
Object.is(+0, -0); // false
Object.is(-0, -0); // true
Object.is(0n, -0n); // true
// Case 3: NaN
Object.is(NaN, 0/0); // true
Object.is(NaN, Number.NaN) // true
オブジェクトをフリーズ Object.freeze()
文法:Object.freeze(obj)
Object.freeze()
オブジェクトをフリーズするメソッド。凍結されたオブジェクトは変更できなくなります。オブジェクトが凍結されると、新しいプロパティをオブジェクトに追加したり、既存のプロパティを削除したりできなくなり、オブジェクトの既存のプロパティの列挙可能性、構成可能性、書き込み可能性も変更できなくなります。 、既存のプロパティの値を変更することはできません。さらに、オブジェクトのプロトタイプはフリーズした後は変更できません。freeze()
渡されたパラメータと同じオブジェクトを返します
const freezeObj = {
prop: function() {
},
foo: 'bar',
childObj: {
},
childArr: []
}
freezeObj.foo = '第一次修改后的foo' //可修改
delete freezeObj.prop // 可删除
freezeObj.childArr.push(0)
freezeObj.addChild = "增加的数据"
console.log(freezeObj) // {foo: '第一次修改后的foo', childObj: {…}, childArr: Array(1), addChild: '增加的数据'}
//进行冻结
const newObj = Object.freeze(freezeObj); // 作为参数传递的对象freezeObj与返回的对象newObj都被冻结,也不用保存返回的对象(因为两个对象全等)
newObj === freezeObj // true,
newObj.foo = '第二次修改,No改动'
newObj.childArr.push('第二次修改,可以改动,freeze只冻结第一层')
newObj.addNewChild = "第二次增加数据,No新增"
newObj.childObj.addName = "对对象里层的数据修改,可以新增"
console.log(newObj)
// {foo: '第一次修改后的foo', childObj: {…}, childArr: Array(2), addChild: '增加的数据'}
// childArr: (2) [0, '第二次修改,可以改动,freeze只冻结第一层']
//childObj: {addName: '对对象里层的数据修改,可以新增'}
オブジェクトを不変にするには、Object 型のすべてのプロパティを再帰的にフリーズします (ディープ フリーズ)。
エピローグ
知識ポイントを習得するには、まだ明確にする必要があります。学習することによってのみ、継続的に進歩することができます。