对象,即一组数据的有规律,有属性方法的集合,从构成来看有两组构成方式:字面量,和New构造,
let singer = { name: '张韶涵' ,sex: '女' ,area: ‘中国台湾’ , sing:function(){ conssole.log('浮云') },
上述中 “singer”就是一个简单的对象,singer是对象名,花括号内部是关于这个singer对象的一些属性和值,方法,属性“name:‘张韶涵’ ”,name是其属性名(key),‘张韶涵’是其属性值(value),也可以写作“name='张韶涵'”,属性与属性之间用逗号,分隔(这里要区别函数内部用分号;分隔)。
另有:
let a = new Singer(){};
上述为对象的构造函数方式,和其他构造函数相似的,关键词“new”不可省略,且为了规范和方便阅读,其对象名首字母要大写,且后面跟小括号而不是花括号,相对于第二种,博主更推荐上述字面量方法。
一些难点:
首当其冲的就是面试难题,this在对象中的应用,
构造函数里面的this,用于给类定义成员(属性和方法),即this.name或this.sex即调用这个函数的调用者,上式中即为(张韶涵,女)
方法里面的this,指向方法的调用者(此时该方法的调用者不能是一个函数)
箭头函数中没有this,如果在箭头函数中使用了this,会向外层寻找this的指向
如果所有的外层都没有this,最终会指向window对象
注意:用于var定义的成员(变量和方法)都会成为window对象的成员
上述中,是一个多层嵌套的对象和this的运用,自由上而下来看,该代码总共会输出4个值,分别在第21行,第22行,第29行和第31行,让我们逐个进行分析,
第21行,fun(),fun变量指a.say,即可看作a.say(),但要注意的是此刻的fun是作为函数调用的而不是对象,所以该函数中的thi实际上并不指向对象a,而是指向了window,即(window.fun()),所以此刻打印结果是window对象,其变量为全局变量,即为 最外层var name 赋值的全局变量222
第22行,a.say(),say属性里是一个匿名函数,this的调用者为对象本身,虽然var赋值的对象是当做全局变量看待的,但是对象a内部对name重新赋值过了,所以此时name为111,即打印111,
第29行,b.say(a.say),把a.say传入到b.say中,即25行为:say : function(a.say){...},但是不论调用者,自上而下看b.say本身就是一个调用函数,a.say是其一个回调函数,函数的this会向外寻找其指向对象,即(window.(b.say)),所以此时的this还是指向window的,因为作用域没有发生变化,全局变量name的值还是222,因此此时打印的也同样是222,
第31行,b.say(),按照上面的理解此时答案已经很清楚了,b是对象,say()是对象b的属性(或者说方法),那么此时say()里面的this即指向b,由于b里面name值已经重新赋值333,因此此时打印的就是333,让我们输出一下并打开控制台检查一下看看结果:
果然,结果如我们所见!
那么怎么解决这种嵌套定义中对象的this问题呢?
1.可以在方法函数的内部首先放置好其他的“this”,即:
say:function(){ let that = this .......}, 意思是这里先引用一个this,由于say是函数,这个this便会指向调用这个函数的对象本身,那么这里的this就可以固定引用了,不管函数后面怎么定义变量名,使用that即可轻松的指向对象本身了
2,使用ES6新增的箭头函数,可以理解为say这个函数里再套用一个箭头函数,由于函数调用this指向为他本身的对象,所以这样也可以避免调用错误,
3,使用call() ,apply(), bind()方法,
使用call()改变方法里面,this的指向
call()方法的第一个参数必须是指定的对象,方法的原有参数,挨个放在后面
使用apply(),也可以改变方法里面this的指向,第一个参是指定的对象,方法的原有参数,统一放到第二个数组参数中。
使用bind(),也可以改变方法里面this的指向,用法给call()一样
call()是直接运行方法,bind()是返回新的方法,然后再重新调用。
这里博主做个扩展,使用两个方法:
1.将规定格式的字符串转换为对象,
感兴趣的游客可以试试这种格式的字符转换成对象是什么样子的
2.将对象转换成字符串:
同样,博主这边留个白(摸个鱼)就不展示了,感兴趣的游客可以自行实验实验。
以上为博主一些笔记和分析,如需互动请关注博主私聊哦!