对象创建方法
对象字面量
- 是创建对象最简单最常用的方法
var obj = {};
复制代码
构造函数
- 构造函数就是提供一个生成对象的模板并描述对象基本结构的函数;一个构造函数可以生成多个对象,这些对象都有相同的结构
- 构造函数也是正常的函数,为了区分它和别的正常函数,把构造函数的函数名首字母大写
- 函数体内使用的
this
关键字代表所要生成的对象实例 - 生成对象时必须使用
new
命令来调用构造函数,所以构造函数更合理的理解应该是函数的构造调用
new
命令的作用就是执行一个构造函数且返回一个对象实例。使用new
命令时,它后面的函数调用就不是正常的调用,而是依次执行下面的步骤
1、创建一个空对象,作为将要返回的对象实例
2、将空对象的原型指向了构造函数的 prototype 属性
3、将空对象赋值给构造函数内部的 this 关键字(构造函数内部,this 指向的是一个新生成的空对象,所有针对 this 的操作都会发生在这个空对象上)
4、开始执行构造函数内部的代码- 构造函数分两种:
系统自带的构造函数
和自定义的构造函数
- 系统自带的内置构造函数
- 创建对象的构造函数是
Object() -> var obj = new Object()
, 它的作用和var obj = {}
的作用是一样的 - 系统自带的还有很多:
Number()
、String()
、Array()
、Boolean()
、Date()
等
- 创建对象的构造函数是
- 自定义构造函数:最常用的一种构造函数:
function Person() {}
function Person(name) { // var this = {} this.name = name; // return this } var person = new Person('Tina') 复制代码
- 若在构造函数首行手动创建一个对象,比如
that
对象且最后返回了that
,那里面的this
就不起作用,要为属性赋值就要用that
function Person(name) { var that = {name: 'aa'} that.name = name; return that } var person = new Person('Tina') 复制代码
- 若在构造函数首行手动创建一个对象,比如
- 注意:若最后返回的是对象,那么
this
失效,但若最后显示返回的是原始值,那this
还是有效的function Person() { var that = {} that.name = "aa"; this.name = 'bb'; return 123; } var person = new Person() person.name // 'bb' 复制代码
- 若对普通函数(内部没有
this
关键字的函数)使用new
命令,则会返回一个空对象function Keith() { return 'this is a message'; } var boy = new Keith(); console.log(boy); // Keith {} 复制代码
上面代码中,对普通函数
Keith
使用new
命令会创建一个空对象。这是因为new
命令总是返回一个对象,要么是实例对象要么是return
语句指定的对象或数组。本例中return
语句返回的是字符串,所以new
命令就忽略了该语句
Object.create(原型)
对于创建一个对象来说,更推荐使用字面量的方式创建对象,因为使用 new Object() 的方式创建对象需要通过作用域链一层层找到 Object,但是使用字面量的方式就没这个问题
属性的增删改查
增
:可以通过对象名+点+属性名
的方法来给对象添加新的属性并且赋值改
:修改的操作和增加的操作其实是一样的,只要调用相同的属性名然后赋一个新的值就可以了查
:对象名+点+属性名
、对象名[属性名]
删
:delete
操作符,其作用就是来删除属性的
包装对象
在 JavaScript 中有三种包装对象,它们对应的构造函数分别是
String
、Number
、Boolean
,这三个包装对象对应着三个原始类型:字符串、数值和布尔。而原始数据类型是没有属性和方法的,它们就是单纯的值,若希望获取它们的属性或调用方法,那就需要包装对象来帮忙,原始类型会先通过其包装对象对应的构造函数转换成对象,然后用这个对象调用方法或使用属性,结束后原始类型仍是原始类型,新创建的包装对象会被销毁
注意:
undefined
、null
无包装对象
原始值是不可以改变的,只有对象才有属性和方法,那下面的结果是为什么?
var str = 'abcd';
console.log(str.length) // 4
复制代码
按理说这个字符串原始值是没有 length 属性的,但实际确实可以查看 length 这个属性
这就涉及到一个叫做包装类的东西,在调用执行这一行代码之前,程序会自动把 str 包装成一个字符串对象,该对象上面有属性和方法,在这一行代码执行完毕之后再销毁这个字符串对象
var str = 'abcd';
// var str1 = new String('abcd')
str.length // str1.length
// 销毁str1
复制代码
这也就是为什么在执行 str.length = 2; 这句话后再打印 str.length 还是 4 的原因:系统在执行 str.length = 2 时,先创建了一个 String 对象,这个对象的值是 ‘abcd’,改变的 length 其实是这个隐式创建的对象的 length 值,并不是改变了原始值 str,当 str.length = 2 这句代码执行完后隐式创建的字符串对象就被销毁了,所以打印的 str.length 还是 4
var str = 'abcd';
// var str1 = new String('abcd')
str.length = 2 // str1.length = 2
// 销毁str1
console.log(str.length) // abcd长度还是4
复制代码
其他类型的数据也是一样的,当给原始值加属性时都是先隐式包装成对象,然后赋完属性值之后再销毁这个对象