JS对象

基础定义

  • 对象是一组无序的集合
  • 对象是键值对的集合

正确理解JS对象与Object的关系

  • JS对象是JS中七大数据类型之一,这是数据类型层面的叫法
    • Object,这个JS对象分支非常有迷惑性
    • Function
    • Array 以及等等
  • Object Function 等等这些叫做类,是JS对象的分支,也代表构造函数,分别能够创建object对象,function对象等等
typeof(42); 'number'
typeof(new Number(42)); 'object'
复制代码

正确访问对象属性

node.style.border ✔
node.style."border"for(let key in obj){
	console.log(obj[key]) √
    console.log(obj.key)  ❌    <=====>  console.log(obj["key"]) 把变量key弄成字符串key了
}
复制代码

对象中的属性名一定是双引号的字符串

当你不写双引号或者写成单引号时JS会为你转化为双引号!

let obj={name:'ryan','age':18}
Object.keys(obj) // ["name", "age"]
复制代码

重要概念

  1. 如果一个对象不存在一个键名,则会报undefined
  2. 如果一个对象存在一个键名,但值是undefined,也会报undefined
  3. 如果一个对象的键名报出null,则说明该键名是存在的,且值也是存在,只不过为null
  4. 不推荐使用obj.--proto--的操作,因为该隐藏属性在不同浏览器下名字会有不同
var obj={name:undefined};
// 情况1
console.log(obj.bbb) // undefined
// 情况2
console.log(obj.name) // undefined
// 情况3
console.log(obj.__proto__.__proto__) // null
// 如果你实在不信obj.__proto__.__proto__这个属性是存在的,只不过是值为null的话
console.log('__proto__' in obj.__proto__) // true
复制代码

obj.--proto--.--proto-- === null // true

翻译一下:

  • --proto--是每个obj存在的一个隐藏属性
  • --proto--存放着一个指向名叫prototype原型的地址
  • prototype原型存放着所有对象的公有方法
  • 每个对象的原型是存在的,这是常识
  • 并且原型的原型也是存在的
  • 如果不存在,则会报出undefined
  • 但是原型的原型是指向null,不是undefined,说明原型的原型是存在的,只不过被人为赋值null

一道重要的题目先检测是否掌握重要的特性

let list = ['name','age','gender'];
let person = {
    name:'frank',age:18,gender:'man'
}
for (let i=0;i<list.length;i++){
let name=list[i]
console.log(person___???___) 
// 这里应该A: console.log(person.name) 
// 还是B: console.log(person[name])
}
复制代码

对象键名会转化成字符串

输入的值会在内部转化一下

var obj={2:2} // chrome欺骗你让你以为你输入的数字2在对象内也是数字
Object.keys(obj) // 原形毕露 ["2"]
var obj={1e2:2,0xFF:100}
Object.keys(obj) // 先转成数字100再转成字符串'100'
复制代码

用变量当作对象的键名

var a=123;  // 看似a是123数字
var obj={[a]:123}; // 实际a是'123'字符串
Object.keys(obj) 
var obj={[1+2+3]:123}; // 还支持js表达式,最终是转成字符串
Object.keys(obj) 
复制代码
// 以上的新写法等价于老写法:
var a=123;
var obj={}
obj[a]=123;
Object.keys(obj) 
复制代码

每个对象都有一个隐藏属性--proto--

var obj={123:123};
obj.toString(); //这个方法哪来的呢?
复制代码
  • 隐藏属性--proto--存着一个地址
  • 这个地址指向存储着公有方法的地方
  • 这个地方叫prototype原型

'keyName' in obj 与 obj.hasOwnProperty('keyName') 的区别

  • 'keyName' in obj 会逐一排查原型链
  • obj.hasOwnProperty('keyName') 不会排查原型链,只会检查自身
let prototypeObj={name:'ryan'};
let obj=Object.create(prototypeObj); // 篡改了原型链并创建了新对象obj
'name' in obj; // true 因为顺着原型链找到obj.__proto__
'toString' in obj; // true 因为顺着原型链找到obj.__proto__.__proto__
obj.hasOwnProperty('name'); // false
复制代码

增删改查

增改

批量赋值

let obj={};
Object.assign(obj,{p1:1,p2:2,p3:3,p4:4});
console.log(obj);
复制代码

如何修改对象上的公有属性

let obj={};
obj.__proto.toString=123; // 不推荐,因为隐藏属性在不同浏览器中名字不同
window.Object.prototype.toString=123; // 推荐
复制代码

如何修改一个对象的原型链 或者说修改隐藏属性

let obj={},prototypeObj={name:'ryan',gender:'male'};
obj.__proto__=prototypeObj; // 不推荐
console.log(obj) 
复制代码

点击箭头逐一展开可以看到

  • obj自身为空
  • obj.--proto--被人为篡改为obj1
  • obj.--proto--.--proto--才能真正调用到原本为篡改前的toString()

let obj = Object.create() 创建一个对象并指定其原型

obj.--proto-- = obj1 可以做到但是不推荐

// 推荐做法
let prototypeObj={name:'ryan',gender:'male'};
let obj=Object.create(prototypeObj); // 把prototypeObj替换原有的__proto__并创建新对象obj
console.log(obj);
Object.assign(obj,{person:1}); // 批量创建obj的属性
console.log(obj);
复制代码

查(Object.keys/values/entries() )

  • keys 看键名
  • values 看值
  • entries 看键与值

如何查看对象拥有的prototype中的公有属性

console.dir(obj)

如何判断属性是私有的还是公有的?

obj.hasOwnProperty('toString') // false
obj.__proto__.hasOwnProperty('toString') // true 在原型prototype上当然是自身的
复制代码

查看键名对应的值

  • obj['keyName']
  • obj.keyName
  • obj[keyName] // 这是错误的 这里keyName是一个变量名
var name='123'
var obj={};
obj[console.log(name)];
// 会得到undefined,过程如下:
// console.log()永远返回undefined
// 然后obj[]会自动把undefined===> 'undefined'
// obj['undefined'] 没有的键名当然返回undefined
复制代码

删(delete操作符通常只删属性名)

删除对象中的一组键值对以下两种方式

  • delete obj.xxx
  • delete obj['xxx']
var obj={name:'ryan',gender:'male'};
obj.name=undefined;
console.log(obj);
delete obj.name; // 方式1
console.log(obj);
delete obj['gender']; // 方式2
console.log(obj);
'name' in obj; // in 的操作 用于判断对象中是否存在'name'这个属性名
复制代码

obj.oneKeyName === undefined 返回true的话 会有个坑

// 可能存在以下两种情况
var obj={}
obj.oneKeyName === undefined // true 情况1
var obj={ oneKeyName:undefined } 
obj.oneKeyName === undefined // true 情况2
复制代码
  • 对象自身不存在这个键名时,会返回undefined
  • 对象自身存在这个键名时,但值确实为undefined
  • 但作为程序员肯定是要 分清楚到底是情况1还是情况2的,
  • 因此obj.oneKeyName === undefined这个方式分不清

那么如何去判断一个对象存在一个键名,且值是undefined呢?

var obj={name:'ryan'};
'name' in obj && obj.name === undefined
复制代码
分类:
前端
标签: