作者:烨竹
JS面向对象简介
JS名言:万物皆对象
JS面向对象比PHP简单很多;因为JS中没有class关键字,没有经典的类.
由于没有标准的类,也就没有访问修饰限定符public、private、protected。
由于没有标准的类,也就没有extends、范围解析操作符::;
对象与构造器
临时包装对象
在JS中,有一种临时包装对象机制。当对一个基本数据类型,以对象的形式进行引用(访问变量的属性)时,系统会根据变量的数据类型产生临时包装对象
临时包装对象机制:
临时:在把一个变量以对象的形式引用时,会产生临时对象。引用一结束,对象就会被释放。
包装:系统在产生临时对象时,还会捆绑打包上一些属性和方法。典型:str.length
对象:通过这种机制,可以让基本类型数据偶尔具备对象特性(万物皆对象)
自定义对象
在JS中,可以通过大括号定义对象。以冒号:构成键值对,以逗号,分隔键值对
封装创建对象函数(工厂模式)
把对象作为函数的返回值,可以批量产生对象。并且由形参来接收要赋予的属性值
该函数被调用后,会返回一个对象,很像构造方法
自定义构造器
在JavaScript中,由于没有class关键字,取而代之的是有函数来承担构造方法的角色。
在JS想定义类,只能定义构造器(构造器的本质是函数)
创建对象 new 构造器名();
Object系统构造器(系统类 基类)
Object是系统自带的构造器,可以直接new Object创建空对象。
Object.create(被克隆的对象);返回一个克隆的对象
对象成员
对象成员只有属性。如果一个属性保存了函数,那么它就是方法
由于属性名不具备连续数值的特征,所以只能用for…in循环进行遍历
可以用delete关键字 删除对象成员
遍历对象时,循环控制变量要用方括号的形式访问:
this关键字(重点)
this的指向取决于如何调用
this指向调用方法的对象;(场景1~3)
this指向正在实例化的对象;(场景4)
this的五种场景:
① 行内绑定:this指向触发事件的主体
② 动态绑定: this指向触发事件的主体
③ :全局函数:this指向调用方法的对象
btn.onclick(); 当中的this指向btn
window.函数名(); 函数中的this指向window。全局函数中的this指向window对象
④ :在构造器中:this指向正在实例化的对象
⑤ :在定时器或延时器中,this指向window对象:
第一种:
第二种:
第三种:
在行内绑定中,绑定的是一个全局函数:
这种形式实际上只是调用一个全局函数,this依然指向window
第四种:
第五种:
传参时,obj.test只是作为实参,把函数传入setTimeout当中,并不是以obj作为调用者。还需要经过系统函数setTimeout中另外调用
call与apply方法:
call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向;
举个例子:
让对象b调用了自身不具备的方法(a.speak),还把speak方法中的this指向改为b
区别与使用
call与apply的功能一致,传参的形式有所不同:
call方法,后续参数,以逗号分隔(以正常传参形式)写入,apply方法,后续参数,以一个数组包含,传入即可(call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。)
JavaScript 中,某个函数的参数数量是不固定的,因此要说适用条件的话,当你的参数是明确知道数量时用 call ;而不确定的时候用 apply,然后把参数 push 进数组传递进去;当参数数量不确定时,函数内部也可以通过 arguments 这个伪数组来遍历所有的参数;
原型对象与原型链
原型对象不是构造器产生的,是系统产生的
构造器访问原型对象(灯泡图纸与工厂关系密切):
构造器.prototype 访问原型对象
对象访问原型对象(灯泡产品与灯泡图纸 关系密切):
普通对象.proto 访问原型对象
原型对象访问构造器(灯泡图纸与灯泡工厂关系密切):
原型对象.constructor 访问构造器
原型链访问原则:尝试访问一个对象的属性时,需要遵循原型链的原则
1、 当引用一个对象属性时,现在当前对象内部寻找,如果找到,直接使用
2、 如果没找到,向其原型对象上继续寻找,如果找到,直接使用
3、 如果没找到,继续向原型对象的原型寻找这个属性,以此类推…
4、 如果知道原型链的终点null,依然没有的话,返回undefined
包装对象验证
字符串包装对象的构造器是String()
数值型包装对象的构造器是Number()
布尔类型包装对象的构造器是Boolean()
除了null和undefined以外,其他的所有数据类型,实际上都有对应的构造器
解决临时对象上属性被回收的问题:把属性寄存在原型链的任意一环即可
JS面向对象特性
模拟静态成员
静态成员的代码特征: 可以直接通过类名调用
JS模拟私有成员
私有成员的代码特征: 只能在类内部访问 不能在类外部访问
JS模拟继承(重难点)
对象传递
值传递与引用传递
作为参数
作为返回值
利用对象或数组形成多闭包
创建对象五大方式
1 工厂模式函数和自定义构造器
2 原型模式
以上模式被称为原型模式,只要是所有对象都具备的属性,应该放在原型对象上。好处是,可以节省空间,把普通对象上多个重复的属性,只保存一份,放在原型对象上。
坏处是:个性化的数据,如果保存在原型对象上,会导致相互覆盖。虽然属性名一样,但是属性值不一样,不应该放在原型对象上。
3 混合模式
对原型模式的改进,趋利避害。
如果属性名和属性值都一样,放在原型对象上,节省空间
如果属性名一样,但是属性值不一样,由普通对象自身进行保管。
既含有普通模式,用于保存个性化数据。又利用原型模式,保存共有数据。混合模式。
小缺陷:每次实例化的时候,都会执行this.proto.subject = ‘php’,很没有必要
4 动态原型方式
实现公有属性只创建一次: