JS对象与函数

819 阅读4分钟

1.对象的定义

  • 无序的数据集合
  • 键值对的集合 写法:
var a = {'name':'zhangsan','age':'18'};
let b = new Object('name':'zhangsan');//正规写法
console.log({'name':'zhangsan'});//匿名写法

注意:

  • 1.键名是字符串,不是标识符,可以包含任意字符。
  • 2.引号可以省略,省略后就只能写标识符了,就算省略引号,键名还是字符串。
  • 3.尽量不要省略引号,举例:
  • 4.键名需要使用变量的值时,可用[]获取,举例: 对比:不加[]的属性会自动变成字符串,加了[]的属性,会当作变量求值。

属性名:每个key都是对象的属性名。可以使用Object.keys(obj)方法得到obj对象的所有key值。

属性值:每个value都是对象的属性值。可以使用Object.values(obj)方法,查看obj对象的所有value值。

属性名与属性值:可以使用Object.entries(obj)查看对象的的属性名与属性值。

2.对象属性的增删改查

2.1 删除属性
  • delete obj.xxx 或者 delete obj['xxx']可以删除objxxx属性。 需要注意:
    1. JS中,删除对象不存在的属性,不会报错。举例:
  1. 删除之后,可以使用'xxx' in obj查看xxx属性是否在obj中。接着上面的例子:
2.5 查属性
  • 查看自身所有属性:Object.keys(obj)
  • 判断一个属性是自身属性还是共有属性:obj.hasOwnProperty('xxx'),举例:
2.6 修改或增加属性
  • 增加属性:使用Object.assign(obj,{'xxx':'aaa','yyy':'bbb'}),举例: 通过这种方式可以批量增加属性。
  • 修改属性,可直接通过赋值修改属性: 如果对象没有这个属性,那么就增加该属性:
2.7 如何自定义对象的原型

\quad 我们知道,JS中的对象有一个共有属性组成的集合,我们称之为原型。那么,可不可以自己定义对象的原型。可以通过Object.create(common)实现。举例: 类似于Java中的继承关系。

3.JS函数

3.1 构造函数

使用构造函数new对象的时候,JS自动做了如下四件事情:

  • 1.自动创建空对象
  • 2.自动为空对象关联原型
  • 3.自动将空对象作为this关键字运行构造函数
  • 4.自动return this
3.2 构造函数X()
  • X函数本身负责给对象本身添加属性
  • X.prototype对象负责保存对象的共用属性。举例:
  • 如何确定一个对象的原型
let obj = new Object(); //原型就是Object.prototype
let arr = new Array(); //原型就是Array.prototype;
let fun = new Function(); //原型就是Function.prototype

所以我们可以总结出:

对象.__proto__ === 其构造函数的prototype;

注意一个特殊情况:Object.prototype的原型是null 了解到上面的知识时候之后,我们就可以通过原型定义对象的构造函数。举例: \quad JS在ES6引入了一种更加广泛的写法,与Java类似,使用class声明对象,在class的constructor中声明构造函数。举例,使用class重写上面的代码: 与此同时,ES6还引入了更多概念:

class Person{
  static gender; //静态变量,可以直接通过Person.gender访问
  get name(){    //name为只读属性,不可修改
    return this.name;
  };
}
3.3 class中两种函数的声明方式
语法1class Person{
    sayHi(name){}
    // 等价于
    sayHi: function(name){} 
    // 注意,一般我们不在这个语法里使用箭头函数
}
//等价于
function Person(){}
Person.prototype.sayHi = function(name){}

语法2:注意冒号变成了等于号

class Person{
  sayHi = (name)=>{} // 注意,一般我们不在这个语法里使用普通函数,多用箭头函数
}
// 等价于
function Person(){
    this.sayHi = (name)=>{}
}

4.易混淆概念

4.1 [X]的原型等价于x.__proto__所指的对象,还是x.prototype所指的对象?

每个实例对象( object )都有一个私有属性(称之为 proto )指向它的构造函数的原型对象(prototype )。该原型对象也有一个自己的原型对象( proto ) ,层层向上直到一个对象的原型对象为 null。根据定义,null 没有原型,并作为这个原型链中的最后一个环节。--MDN
所以我们可以知道:

  • 1.「x 的原型」等价于「x.__proto__ 所指的对象」 ,有时为了方便,我们可以认为「x 的原型」等价于「x.__proto__ 」
  • 2.x.__proto__和 Object.prototype 存储着同一个对象的地址,这个对象就是 x 的原型
  • 3.每个对象都有原型,但除了「根对象 Object.prototype」比较特殊,Object.prototype 这个对象的原型为空 null
4.2 prototype属性是所有的对象都默认拥有的么?

我们知道:

  • 1.所有函数一出生就有一个 prototype 属性
  • 2.所有 prototype 一出生就有一个 constructor 属性
  • 3.所有 constructor 属性一出生就保存了对应的函数的地址
  • 4.如果一个函数不是构造函数,它依然拥有 prototype 属性,只不过这个属性暂时没什么用 但是需要注意:
  • 如果一个对象不是函数,那么这个对象一般来说没有 prototype 属性,但这个对象一般一定会有 __proto__ 属性

5.参考资料