js学习整理(二)-面向对象
一、对象及对象属性的操作
js中对象是键值对的集合,有属性和方法构成(注:对象中的方法也可以看做是属性)。对象属性的操作如下:
- 属性的获取和添加:obj.属性名或obj[属性名] (注:使用obj.属性名时其属性名不能为数字,但是可以使用obj[属性名]添加以数字作为属性名的属性)
var obj={} //声明一个变量并进行初始化赋值一个空对象 obj.name='hello' //给obj对象添加name属性,并赋值‘hello’ obj['age']=18 //给obj对象添加age属性 console.log(obj.name,obj.age) //获取对象的属性
- 删除对象的属性: delete obj.属性名
delete obj.name console.log(obj.name) //输出undefined,当一个对象的属性不存在时其值为undefined
- 清空对象属性:obj={}(注:obj=null不是清空对象属性,而是改变变量的值,该变量不再是个对象)
二、构造函数
任何函数都可以当成构造函数,只要一个函数通过new的方式调用就把这次调用称为构造函数调用
function Student(name,age){ this.name=name; this.age=age; this.study=function(){ console.log('study hard!',this); } } var stu1=new Student('张三',18); //变量stu1就是Student的实例,也是通过构造函数Student(name,age)构造出的对象
注:通过构造函数创建的对象未必一定是该函数的实例,是否为该函数的实例,要看该函数的返回值是什么
function Student2(name,age){ return [1,3,5] } var student2=new Student2();//这里student2不是Student2函数的实例,而是Array的实例
一个函数没有返回值或返回值是基本数据类型,则本次返回值是该构造函数的实例;若一个函数的返回值是复杂数据类型(对象或数组),则本次构造函数的返回值是该复杂数据类型
要判断一个对象是否是某个函数的实例通过instanceof进行判断:stui instanceof Student //true
三.继承
- 继承是通过某种方式让一个对象可以访问到拎一个对象中的属性和方法。
- 相同的构造函数new出来的实例中的属性和方法都是不同的(没有指向同一块内存)。为了减少内存浪费,一般把公共的方法都写在它们 共同的父对象(原型对象)中,一个对象的父对象为
构造函数名.prototype
或对象._proto_
Student.prototype.student=function(){}//将student方法方法Student的原型上
- 只要往构造函数的prototype(原型)对象中添加新的属性、方法,name这样的属性方法可以被该构造函数所有的实例所共享
四.继承的实现方式
- 1) 原型链继承
先改变原型对象,再创建对象
function P(){} P.prototype={ name:'人' } var p1=new P(); console.log(p1.name);//'人'
注:一个对象在创建时就会确定其原型对象(原型对象的内存地址不变,属性可修改,但是改变原型属性指向的对象不会对已创建对象原型产生影响)
//如上构造函数P及对象p1,修改其原型对象的属性 P.prototype.run=function(){console.log('我会跑')} p1.run();//输出我会跑 //改变构造函数的原型属性指向对象 P.prototype={eat:function(){console.log('我需要吃饭')}}; p1.eat()//报错,eat is not a function
- 2)原型链继承2
P.prototype={ construnctor:P, a:function(){}, b:function(){} }
- 3)拷贝继承
通过创建一个对象的拷贝实现对另一个对象的属性的继承var obj1={name:'hello',age:18} var obj2={} obj2.name=obj1.name; obj2.age=obj1.age;
- 4)原型式继承
创建一个继承有某个父对象的子对象,使用Object.create(父对象)var obj1={name:'hello'} var obj3=Object.create(obj1); console.log(obj3.name);//'hello'
注:Object.create(null)创建的是一个没有任何属性的对象(没有原型对象)
- 5)借用构造函数实现继承,使用
其他构造函数.call(this,argumnets)或apply方法
function A(a,b){ this.a=a; this.b=b; } function B(a,b,c){ A.call(this,a,b); this.c=c; } let b=new B(1,2,3); console.log(b);
注:call和apply方法是使用指定的对象调用方法,其中两个方法的第一个参数都是指定的对象,区别在于call方法多个参数使用逗号隔开,apply方法则使用参数数组传递参数。若没有指定方法的调用者则默认为全局对象window