一、创建对象得方式
1、对象字面量
如:const obj = {}
const obj = {} // 优点:创建简单方便 // 弊端:创建多个对象麻烦、安全隐患(不利于属性值的验证)
2、工厂模式
function createStudentObj(name,cls){ return { name, cls, study(){ console.log(`我是${this.name},我能够快乐的学习`); } } } const zs=createStudentObj('zs',18) const lisi=createStudentObj('lisi',18) const wangwu=createStudentObj('wangwu',18) // 优点:创建多个对象方便 // 缺点: //问题1:使用工厂模式创建的对象 类型一致 都是Object类型 console.log(zs,lisi,wangwu); //问题2:相同的逻辑代码(函数)被保存到了不同的内存空间中 导致内存空间的一个浪费 zs.study=123
3、构造函数
//构造函数:就是js中的类,本质上就是一个函数 只不过这个函数被new关键字调用了 function Test(){ console.log(123); } new Test //构造函数的特点: 首字母大写的 被new关键字调用的 //使用构造函数创建对象 function Student(name,age){ // this 代表的就是构造函数返回的对象 this.name=name this.age=age this.study=function(){ console.log(`我是${this.name},我能够快乐的学习`); } } const maliu=new Student('马六',18) const tianqi=new Student('田七',18) console.log(maliu,tianqi);//打印的结果是Student类型的对象 // 优点:创建多个对象方便 // 缺点:每个对象都有相同的数据,浪费内存。
4、构造函数+原型
function Person(name, age){ this.name = name this.age = age } Person.prototype.setName = function(name){ this.name = name } var p1 = new Person('Tom',18) // 适用场景: 需要创建多个类型确定的对象。 // 优点:每个实例有自己的属性,同时又共享着方法的引用,还支持传参数
二、原型和原型链
1、原型
什么是原型?
每一个函数身上都有一个prototype属性
prototype : 函数的显示原型属性
函数.prototype :函数的原型对象
每一个对象身上都有一个 [[Prototype]]属性
[[Prototype]]:称之为对象的隐式原型属性
在浏览器中获取隐式原型属性的属性值:对象.proto / Object.getPrototypeOf()
function Student(name,age){ // this 代表的就是构造函数返回的对象 this.name=name this.age=age } Student.prototype.study=function(){ console.log(`我是${this.name},我能够快乐的学习`); } const maliu=new Student('马六',18) console.log(maliu.__proto__===Student.prototype);//true console.log(Object.getPrototypeOf(maliu)===Student.prototype);//true
2、原型链
原型链: 每个实例对象身上都有一个隐式原型属性(在浏览器中展示效果 [[Prototype]] 获取 对象.proto)隐式原型属性指向该对象对应的构造函数的原型对象
当一个对象.属性 时 首先从自身查找 找到即返回 如果自身没有找到该属性则会沿着__proto__查找对应的原型对象 直到 原型链的最顶端 找到则返回 如果一直没有找到则返回undefined
原型链的最顶端是 Object.prototype
function Student(name, age) { // this 代表的就是构造函数返回的对象 this.name = name this.age = age } Student.prototype.study = function () { console.log(`我是${this.name},我能够快乐的学习`); } Student.prototype.name='章三' const maliu = new Student('马六', 18) console.log(maliu); console.log(maliu.name); maliu.study() console.log(maliu.toString()); maliu.__proto__ //Student的原型对象 maliu.__proto__.__proto__ //Object 的原型对象 console.log(maliu.__proto__.__proto__.__proto__);
所有的原型对象 都是Object的实例?
错误的! (因为Object的原型对象不是Object的实例)