JavaScript对象(二)
本篇,主要讲了面向对象、this的指向问题,模拟继承过程
分解成各个对象
,建立对象的目的不是为了完成一个步骤,而是为了描述一个事物在解决问题的过程中经历的步骤和行为
。对象作为程序的基本单位,将程序和数据封装其中,以提高程序的重用性,灵活性和可扩展性谁能帮我解决问题
,面向过程重点关注的是解决问题的过程
。创建对象,主要可以分为两类;
//举一个最简单的工厂创建例子
//需要一个对象,直接工厂创建,调用方法就行
var p = createPerson()
function createPerson( name , age ){
var obj = {}
obj.name = name
obj.age = age
return obj
}
ps:工厂创建,就是把创建对象权力交给了他人,自己就只需要把参数告诉工厂就可以了。
//构造函数
function Person( name , age ){
this.name = name
this.age = age
this.say = fuction(){
...
}
}
//实例化一个对象
var p2 = Person()
注意:因为在JavaScript ES5里,就没有面向对象的写法,所以我们这上面的面向对象都是通过模拟来是实现的。在es6里,有class关键字,在类里写一个construct来构造。
我们有没有发现,在控制台打印一个function,把函数体展开就能看到一个prototype,这个prototype并不是我们自己定义的一个属性或者方法,那这个到底是什么呢?
我们把_proto_展开,你会在展开后的最下面还能看到一个_proto_,再展开下一个,发现又有,直到你到Object对象的_proto_。不过这得嵌套了多少层了。其实我们可以理解,这样的_proto_好比是继承关系。a继承了b,b就是a的父亲,那么a里的_proto_指向的就是b。
应用:
比如你要给数组写一个方法,叫做myPop(),删除最后一个元素。
当你写完这个方法后,你可以通过原型方法,给一个数组对象Array叫上这个方法。Array.prototype.myPop = function(){...}
那么,只要是Array类型的变量,就都可以直接调用myPop()方法了
var m = new Man(‘rainbow‘ , 20 )
访问name属性,console.log(m[‘name‘]) //rainbow
for ( const key in m ){
console.log( m[key] )
}
var m = new Man(‘rainbow‘ , 20 )
//删除指定对象 , 执行成员
delete m1.name
ps:删除完后,Man对象就没有name这个属性了。
之前有个typeof,是用来检查数据类型。
e.g.
var m = new Man(‘rainbow‘ , 20 )
m instance of Man //true
m instance of Woman //false
m instance of Object //true,object为任何对象的祖先
var m = {
name : ‘rainbwo‘,
age : 20
}
m.hasOwnProperty(‘name‘) //true
m.hasOwnProperty(‘sex‘) //flase
var m = {
name : ‘rainbwo‘,
age : 20
}
‘name‘ in m //true
‘age2‘ in m //false
‘toString()‘ in m //true
ps: 对比hasOwnProperty、in
this关键字我们不陌生,之前在工厂创建对象时。用到了
this.name = name
this.age = age
其实,这个this指的就是当前的对象,使用this可以不用把调用者本身全部拼写出来,并且易于阅读。
但是,实际上,我们的this指向,并没有那么容易。
比如:
在在全局中,console.log(this). 这个this打印的Window,也叫程序上下文。
在一个方法内部(箭头函数除外),console.log(this),这个this指的就是函数所属的对象
箭头函数的this指向,Window
在事件函数中,this指向事件本身。
setTimeout,setInterval的this指向Window
Function.prototype.xxx()
//定义test函数
function test(attr1,attr2,attr3) {
this.attr1 = attr1
this.attr2 = attr2
this.attr3 = attr3
}
//实例化一个对象
var obj = new Object(a , b, c);
test.call( obj , 1 , 2 , 3 )
call直接把this指向了obj
test.apply( obj ,[1 , 2 , 3])
apply指向了obj,并且用一个数组来传参数
test.bind( obj ).(1 , 2 , 3)
test.bind()把this指向了obj,并且返回了一个新的对象
ps:在JavaScript的语法里,就只有这三种方法可以改变this的指向
继承就是让子类拥有父类的属性和方法
在es5里,没有继承的语法 ,es6有
所以我们可以来模拟一下
//父类
function Person(name , age ) {
this.name = name
this.age = age
}
//子类
Man 、 Woman
function Man( name , age , job ){
//构造函数的伪装,也就是通过this,改变指向
Person.call(this , name , age )//等价于,调用了Persion()
this.job = job
}
ps:
Man.prototype = Person.prototype
谢谢大家阅读,鄙人知识、能力不足,如果讲的不好或者不正确的地方,还请原谅。支持原创
原文:https://www.cnblogs.com/lovelyk/p/14320416.html