JavaScript高级 创建对象的四种方式:
①直接创建法:
例:创建一个对象:名称,价格 方法:购买商品显示名称
产生多个商品对象 用 js直接创建
好处:创建简单 弊端:无法量产
var chips={
sign:"百事薯片",
price:"15",
buy:function(){
console.log(this.sign)
}
}
var chips1={
sign:"可口薯片",
price:"10",
buy:function(){
console.log(this.sign)
}
}
var chips2={
sign:"薯愿薯片",
price:"12",
buy:function(){
console.log(this.sign)
}
}
console.log(chips)
chips.buy() //百事薯片
----------------------------------------------------------------------------------------------------------------------
②工厂模式 创建:
要求、重复的创建对象,需要创建时可以快速的创建出来
将创建对象的过程 封装到函数内部,直接调用函数进行对象创建
工厂模式:通过函数封装来创建对象
好处:可以量产同类型对象
弊端:无法明确对象的类型,全都是object类型的,无法类型的细分
function chips(sign,price){
let c={} //创建一个空对象
c.sign=sign
c.price=price
c.buy=function(){
console.log(this.sign)
}
return c
}
let c1=chips("百事薯片",15)
let c2=chips("可口薯片",10)
let c3=chips("薯愿薯片",12)
function cigarette(sign,price){
let ci={} //创建一个空对象
ci.sign=sign
ci.price=price
ci.buy=function(){
console.log(this.sign)
}
return ci
}
let ci1=chips("中华",50)
let ci2=chips("散花",5)
console.log(ci1)
console.log(typeof(ci1)) //typeof() 返回对应变量的数据类型
console.log(ci1 instanceof cigarette)//返回false
//为什么返回false 因为用 instanceof 检测变量的数据类型 变量必须为原型创建出来的
js中分为两种数据类型 :简单数据类型:简单数据类型在直接创建时 不走原型
复杂类型 instanceof
变量 instanceof 类型 返回布尔值
typeof() 返回对应变量的数据类型 返回根本数据类型 字符串
var arr=[1,2,3]
//arr变量 检测arr变量是否为数组类型
console.log(typeof(arr)) //object
console.log(typeof(arr)==”object”) //true
//变量 instanceof 类型 返回布尔值
console.log(arr instanceof Array)//true
注:
var num=10 不是原型
var num=new Number(10) 原型
console.log(num instanceof Number) 如果是原型就为真 true 如果不是则为false
----------------------------------------------------------------------------------------------------------------------
③构造函数:
其他的编程语言当中,想要创建对象的话,创建一个类
类:一类事物的统称 包含 属性和方法
Js中没有类概念
构造函数的方式来模拟类!!!利用js this 指向性可以改变的问题
创建一个商品类(构造函数) sign,price,buy方法
this指向 对象 window 固定对象 事件源
this指向运行环境 //window对象
function fun(){
console.log(this)//window
}
fun()
构造函数创建对象
好处:可以明确对应的对象类型
弊端:不同对象中的相同方法,无法公用,需要独立存储,造成内存损耗
function Chips(sign,price){
this.sign=sign
this.price=price
this.buy=function(){
console.log(this.sign)
}
}
function Cigarette(sign,price){
this.sign=sign
this.price=price
this.buy=function(){
console.log(this.sign)
}
}
//通过new来创建对象 new做了什么?
// 1.创建一个空对象 {}
// 2.执行后方函数 让函数内部this指向 空对象{}
// 3.将创建对象 返回出来,赋值给前方变量
var c1=new Chips("百事薯片",15)
var c2=new Chips("可口薯片",10)
var ci1=new Cigarette("中华",50)
// 判断对象类型
console.log(c1 instanceof Chips)//true
console.log(ci1 instanceof Cigarette)//true
//上面的问题解决后那么因为每一个对象 都开辟一个存储buy的空间,所以下面的buy返回f
console.log(c1.buy==ci1.buy)//返回f
//那么相同的方法能否存到一个共同的空间中呢? 有! 通过原型创建
***重点 通过new来创建对象 new做了什么?
1.创建一个空对象 {}
2.执行后方函数 让函数内部this指向 空对象{}
3.将创建对象 返回出来,赋值给前方变量
***
----------------------------------------------------------------------------------------------------------------------
④原型创建:
构造函数创建对象时共有的方法,没办法统一存储,需要独立开辟空间造成内存消耗
发现 每一类相同的对象,原型对象都是一个样,想办法将公有的方法 放到原型中
创建一个商品类(构造函数) sign,price,buy方法
构造函数原型==实例化对象的原型
公用的放在原型中 私有的放入构造函数里 如下代码:
function Chips(sign,price){
this.sign=sign
this.price=price
}
// 将构造函数中的方法,定义到原型中
// 构造函数的原型(prototype)==实例化对象的原型(__proto__)
Chips.prototype.buy=function(){
console.log(this.sign+"被王一购买")
}
let c1=new Chips("百事薯片",15)
c1.buy() //百事薯片被王一购买
let c2=new Chips("可口薯片",12)
c1.__proto__.buy=function(){
console.log(123)
}
c1.buy() //123
let c3=new Chips("aaa",12)
c3.buy() //123
//发现每一个实例化的对象 都存在一个 [[Prototype]]属性 原型
//通过相同构造函数创建出来的对象 原型相同
//获取对象原型__proto__
console.log(c1.__proto__==c2.__proto__) //t
console.log(c1==c2) //f
下面的这个c1和c3为何都变成了123
因为修改了c1对象的原型 因为指向的都是同一个 所以牵一发而动全身都改变了