对象创建的几种方式
字面量方式
优缺点
优点:
创建方式简单, 简洁, 可读性好.
缺点:
001 代码不具备复用性
002 如果需要创建多个类似的对象, 则代码冗余度很高
示例代码
var book = {
name:'js面向对象',
author:'liyajie',
showName:function(){
console.log('书名: '+this.name);
}
}
内置构造函数创建对象
内置构造函数有哪些? 特点是首字母全部大写
String, Number, Object, Boolean, Function , Date, RegExp, Array, Math
优缺点
缺点:
和字面量方式一样, 代码不具备复用性, 如果需要创建多个类似对象, 则代码冗余度还是很高
示例代码:
var book = new Object();
book.name = 'java高级编程';
book.author = 'lihaojie';
book.showName = function(){
console.log('书名: '+ this.name);
}
简单工厂函数创建对象
优缺点
仅仅是对构造函数方式创建对象的封装, 代码仍然不够简洁
本质:
是对使用构造函数创建对象的封装.
示例代码
function createBook(name,author){
var book = new Object();
book.name = name;
book.author = author;
book.showName = function(){
console.log('书名: ' + this.name);
}
return book;
}
// 使用工厂创建一本书
var book1 = createBook('心灵鸡汤', 'liyajie');
var book2 = createBook('心灵鸡汤2', 'liyajie');
自定义构造函数创建对象
优缺点
缺点:
每个对象的方法都是一样的, 每次在创建的时候都会创建方法, 而这些方法都是一样的, 如果每次创建同样的方法优点资源浪费
与工厂方法对比:
- 函数首字母大写, 主要用于区分构造函数和普通函数
- 创建对象的过程是通过new关键字来实现的
- 在构造函数内部会自动创建新对象, 并赋值给this指针
- 自动返回创建后的对象.
构造函数的执行过程 - 默认会使用new创建一个空的对象.
- 把新创建出来的对象赋值给this指针
- 把this.prototype 赋值给创建出来的新对象的proto
- 把this.contrustor 赋值给新创建出来的新对象的constructor
- 在构造函数内部使用this为新创建出来的对象设置属性和方法.
- 默认返回新创建的对象.如果函数没有返回值, 则默认返回的是undefined, 如果我们手动返回一个对象, 那么返回的值就是这个对象 , 如果我们手动返回的是一个值类型的值, 则将忽略.
示例代码
// 创建构造函数
function CreateBook(name,author){
this.name = name;
this.author = author;
this.showName = function(){
console.log('书名: '+ this.name);
}
}
// 使用构造函数创建对象
var book1 = new CreateBook('java高级编程','liyajie');
book1.showName();// 调用showName方法
构造函数的使用注意
- 封装固定不变的部分, 把变化的部分提取为参数.
- 如何检查对象的类型, 使用
instanceof
var person = new Person();
console.log(person instanceof Person);// true
- 获取对象的真实类型
Object.prototype.toString.call(对象实例)
- 函数的调用和this
- 构造器属性
constructor
构造函数的原型对象
什么是构造函数的原型对象?
在构造函数创建出来的时候, 系统会默认为构造函数创建并关联一个新对象, 而这个对象就是原型, 自定义构造函数的原型对象默认就是一个空对象.
作用
构造函数的原型对象上的属性和方法, 可以被该构造函数所创建的对象使用.
即自定义的构造函数所创建出来的所有对象, 将共享原型对象中的所有属性和方法.
如何访问原型
- 构造函数.prototype
- 对象.proto (不推荐使用, 因为有些浏览器解析不到该属性, 这个主要是为了方便开发者调试使用)
- Object.getPrototypeOf(对象)
设置原型对象
- 利用对象的动态特性来设置属性和方法.
- 替换原型对象的时候, 替换前和替换后创建的对象所指向的原型不是同一个.
注意事项
- 访问属性:
构造函数在创建出来的对象在访问原型对象的时候, 首先会先会在实例内查找, 如果没有则取查找原型对象上的属性. - 当我们使用.语法设置对象属性的时候, 无法操作到原型对象上的该属性, 不管增加还是删除. 如果我们需要修改原型对象上的属性和方法的时候需要在访问的时候使用:
构造函数.prototype.属性 = '';
这样才可以 - 设置原型对象的属性和方法
3.1 只能通过构造函数.prototype.属性 的方式来设置或者修改
3.2 如果原型对象的属性是值类型, 只能通过构造函数.prototype.属性 的方式来设置.
3.2. 如果原型的属性是引用类型, 那么可以通过构造函数的实例对象进行修改, 如果是直接覆盖的话则是给实例对象新增了属性.
function Person(){}
Person.prototype.friends = ['小名', '小白','小黄'];
var p = new Person();
// 如果使用实例对象来修改friends,
p.friends.push('小绿');
console.log(p.friends);// ['小名', '小白','小黄', '小绿'];
p.friends = [1,2,3,4];
console.log(p.friends);// [1,2,3,4];