-
Notifications
You must be signed in to change notification settings - Fork 5
Description
this 相关问题
问题1: apply、call 、bind有什么作用,什么区别
-
作用:
- apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
- apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
- apply 、 call 、bind 三者都可以利用后续参数传参;
-
区别:
- bind 是返回对应函数,便于稍后调用,只能绑定一次(多次绑定无效)
var obj = {name: '老王'}
function foo(){
console.log(this.name)
}
var fun = foo.bind(obj) //返回绑定指定this的函数
fun()
- apply 、call 则是立即调用 。
参考:http://www.cnblogs.com/coco1s/p/4833199.html
问题2: 以下代码输出什么?
var john = {
firstName: "John"
}
function func() {
alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() //输出:John:hi!问题3: 下面代码输出什么,为什么
func()
function func() {
alert(this)
}输出: [object window]
func( )等价于func.call(undefined) -->this==undefined
在非严格模式下,undefined指向window
问题4:下面代码输出什么
document.addEventListener('click', function(e){
console.log(this);
setTimeout(function(){
console.log(this);
}, 200);
}, false);输出:document window
问题5:下面代码输出什么,why
var john = {
firstName: "John"
}
function func() {
alert( this.firstName )
}
func.call(john)输出:John //call方法改变了函数func运行时的上下文,及this --> john
问题6: 以下代码有什么问题,如何修改
var module= {
bind: function(){
$btn.on('click', function(){
console.log(this) //this指什么
this.showMsg();
})
},
showMsg: function(){
console.log('饥人谷');
}
}-
this.showMsg()中的this指向的是事件绑定的Dom元素,所以取不到值
- 修改1:
var module = {
bind:function(){
_this = this
$btn.on('click', function (){
console.log(_this)
_this.showMsg()
})
},
showMsg: function (){
console.log('饥人谷')
}
}- 修改2:
var module = {
bind:function(){
$btn.on('click', function (){
console.log(this)
this.showMsg()
}.bind(this))
},
showMsg: function (){
console.log('饥人谷')
}
}原型链相关问题
问题7:有如下代码,解释Person、 prototype、proto、p、constructor之间的关联。
function Person(name){
this.name = name;
}
Person.prototype.sayName = function(){
console.log('My name is :' + this.name);
}
var p = new Person("老王")
p.sayName();Person: 是产生p实例的构造函数,通过Person(name)定义了p对象的name属性和继承方法prototype: 每个构造函数都有一个prototype属性,每个生成的实例都是通过此属性来继承原型的一些方法和属性__proto__: 每个实例对象都有此属性,通过此属性可以继承原型的方法和属性,是原型继承的渠道p:由Person()构造函数创建的一个实例对constructor: 构造函数的prototype下都有此属性,指向此构造函数
问题8: 上例中,对对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
-
原型链:
- 任一对象调用某些属性或方法时,都会先从自身查找
- 当自身不存在时,会通过
_proto__查找原型是否存在 - 若原型也不存在,则继续向上查找原型,类似这样依次查找
- 类似这种关系所形成的联系,形成了原型链
-
javascript原型链图:
问题9:对String做扩展,实现如下方式获取字符串中频率最高的字符
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次String.prototype.getMostOften = function (){
var objStr = {},
max=0,
maxKey
for (var i=0; i<this.length; i++){
if(objStr[this[i]]){
objStr[this[i]]++
}else{
objStr[this[i]]=1
}
}
for(var key in objStr){
if (objStr[key]>max){
maxKey = key
max = objStr[key]
}
}
return maxKey
}问题10: instanceOf有什么作用?内部逻辑是如何实现的?
instanceOf作用:
- 判断一个实例是否属于某种类型
function Foo(){ }
var foo = new Foo()
console.log(foo instanceOf Foo) //true- 在继承关系中判断一个实例是否属于它的父类型
function Foo(){ }
function Aoo(){ }
Foo.prototype = new Aoo()
var foo = new Foo()
console.log(foo instanceOf Foo) //true
console.log(foo instanceOf Aoo) //trueinstanciOf内部实现逻辑
instanceOf通过循环对比隐式原型和显示原型是否相等,以此来做判断。
具体逻辑为下面伪代码
function instance_of(L, R) {//L 表示左表达式,R 表示右表达式
var O = R.prototype;// 取 R 的显示原型
L = L.proto;// 取 L 的隐式原型
while (true) {
if (L === null)
return false;
if (O === L)// 这里重点:当 O 严格等于 L 时,返回 true
return true;
L = L.proto;
}
}参考:https://www.ibm.com/developerworks/cn/web/1306_jiangjj_jsinstanceof/index.html
继承相关问题
问题11:继承有什么作用?
- 生成的实例共享构造函数的属性、方法,节省内存空间
- 在只修改原生对象的情况下,可以同步改变构造实例
问题12: 下面两种写法有什么区别?
//方法1
function People(name, sex){
this.name = name;
this.sex = sex;
this.printName = function(){
console.log(this.name);
}
}
var p1 = new People('饥人谷', 2)
//方法2
function Person(name, sex){
this.name = name;
this.sex = sex;
}
Person.prototype.printName = function(){
console.log(this.name);
}
var p1 = new Person('若愚', 27);方法1:为每个实例都生成了printName方法
方法2:实例没有printName方法,但可以通过原型继承此方法
区别:方法2相对于方法1节省大量空间,但用到printName方法的时候通过原型查找使用,功能性没有损失
问题13: Object.create 有什么作用?兼容性如何?
Object.create: 创建一个新对象,此对象的原型为方法的第一个参数
Object.create(proto [, propertiesObject]) //第一个参数为要继承的原型,第二个参数设置新对象的属性- 第一个参数:要继承的原型
- 第二个参数:
configurable:表示新创建的对象是否可配置,即:新对象的属性或方法是否可删除或修改,默认:falseenumerable:对象属性是否可枚举(for of),默认falsewritable:是否能在新对象上添加新属性,默认falseget:对象getter函数,默认undefinedset:对象setter函数,默认undefined
使用Object.create()方法创建新对象时,如果不是继承一个原有的对象,而是要创建一个全新的对象,就要把proto参数设置为null。如果proto参数不是null或一个对象时,会抛出一个TypeError异常。
参考:https://itbilu.com/javascript/js/EkCyw5lHl.html
- 兼容情况:
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Basic support | 5 | 4.0 (2) | 9 | 11.60 | 5 |
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create
问题14: hasOwnProperty有什么作用? 如何使用?
hasOwnProperty:返回一个布尔值,指示某个属性是否是自身属性(非继承属性)
obj.hasOwnProperty(prop) //返回布尔值所有继承了Object的对象都会继承
hasOwnProperty( )方法,此方法可以用来检测某个属性是否为对象的自身属性,和in方法不同,此方法会忽略从原型上继承来的属性
- 用法举例:
var obj = new Object()
obj.pro = 'hello'
obj.hasOwnProperty('pro') //true
obj.hasOwnProperty('toString') //false
obj.hasOwnProperty('hasOwnPropterty') //false问题15:如下代码中call的作用是什么?
function Person(name, sex){
this.name = name;
this.sex = sex;
}
function Male(name, sex, age){
Person.call(this, name, sex); //这里的 call 有什么作用
this.age = age;
}Person.call(this, name, sex):参数this指定了函数运行上下文,当Male创造实例时,实例对象即为this对象,因此也具有了Person內的属性;- 例:
var male = new Male('老王', '男', 33)
male = {
name: '老王',
sex: '男',
age: 33
}问题16: 补全代码,实现继承
function Person(name, sex){
this.name = name
this.sex = sex
}
Person.prototype.getName = function(){
console.log(this.name)
};
function Male(name, sex, age){
Person.call(this, name, sex)
this.age = age
}
Male.prototype = new Person()
Male.prototype.constructor = Male
Male.prototype.getAge = function(){
console.log(this.age)
};
var ruoyu = new Male('老王', '男', 27);
ruoyu.getName();
