对象
对象:多个数据的封装体,保存多个数据的容器(可以统一管理多个数据)
- 分类:
-
内建对象:由ES标准定义的对象,在任何ES的实现都可以使用,例如:Math String Number Function Object
-
宿主对象:由JS运行环境提供的对象,例如DOM BOM
-
自定义对象:用户自己定义的
-
- 组成:
- 属性:由属性名(字符串)和属性值(任意类型)构成
- 方法:一种特殊的属性(属性值是函数)
- 访问属性
- 对象.属性名:属性名必须是合法的标识符(字母、数字、下划线、$)
- 对象["属性名"]:任何情况下都能使用
- 对象[变量名]:在[]传入一个变量,会读取变量的值代表的属性,操作更加灵活
let obj={
name:'jack'
}
// 属性名必须是合法的标识符(字母、数字、下划线、$)
console.log(obj.name)//'jack'
// 属性名可以是任何字符串
console.log(obj['name'])//'jack'
// 读取的是name变量的值代表的属性,因为变量name=undefined,所以obj.undefined=undefined
console.log(obj[name])//'undefined'
---------------------------------------------------
let flower='rose'
let obj2={
rose:'red'
}
console.log(obj2.rose)//red
console.log(obj2['rose'])//red
console.log(obj2[flower])//red
创建对象
- 1、new操作符:先创建空对象,再动态添加属性。用于最初对象的内部属性不确定时
缺点:语句太多
let obj=new Object()
obj.name='tim'
obj.age=19
- 2、对象字面量:适用于创建时对象内部属性是确定的。
let obj={
name:'jack',
age:19,
sayHello:function () {
console.log('hello');
}
}
缺点:创建多个对象时,大量代码重复
- 3、使用工厂方法:通过工厂函数动态创建对象,并将对象返回。适用于创建多个对象
function createPerson(name,age) {
let obj={}
obj.name=name
obj.age=age
return obj
}
function createDog(name,age) {
let obj={}
obj.name=name
obj.age=age
return obj
}
let person=createPerson('tim',19)
let dog=createDog('bigYellow',3)
console.log(typeof person);//object
console.log(typeof dog);//object
console.log(person instanceof createPerson);//false
console.log(dog instanceof createDog);//false
缺点:对象没有具体的类型,返回都是object,无法判断对象是谁的实例
- 4、构造函数的方式,与工厂函数方式的区别:没有显示的创建对象;没有返回语句;构造函数名需要一般大写,其他一般小写;知道是谁的实例(通过 instanceof 可以看出其既是Object的实例,又是Person的实例)
function CreatePerson(name,age) {
this.name = name
this.age = age
this.sayHello = function () {
console.log('hello');
}
}
let person1 = new CreatePerson('tim', 19)
let person2 = new CreatePerson('jack', 29)
console.log(typeof person1);//object
console.log(person1 instanceof CreatePerson);//true
console.log(person2.sayHello === person1.sayHello)//false
缺点:person1,person2有一个相同的sayHello方法,但是它们并不是同一个函数的实例,创建两个完成同样任务的Function实例的确没有必要;况且有this对象在,根本不用在执行代码前就把函数绑定到特定对象上面。
function CreatePerson(name,age) {
this.name = name
this.age = age
this.sayHello = fun
}
function fun () {
console.log('hello');
}
let person1 = new CreatePerson('tim', 19)
let person2 = new CreatePerson('jack', 29)
console.log(typeof person1);//object
console.log(person1 instanceof CreatePerson);//true
console.log(person2.sayHello === person1.sayHello)//true
缺点:利用函数定义转移到构造函数外部来解决上面的问题,但是当对象有多个方法时就需要在定义多个全局函数,大量占用命名空间并且不安全
总结:如果将方法函数写在构造函数中,那么在每次创建对象时都会实例化一个方法(方法是函数,函数也是对象),所以每个对象的方法都
不一样。将方法函数写在外面又会污染全局命名空间,并且不够隐私。这就出现了原型方式创建对象
- 5、构造函数+原型
function Person(name,age) {
this.name=name
this.age=age
}
Person.prototype.sayHello=function () {
console.log('hello');
}
let p=new Person('jack',19)
p.sayHello()