- 有如下代码,解释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是一个构造函数, 其中prototype是Person的原型对象, p是Person构造出来的实例, 拥有name属性, 属性值是传入的参数若愚, p拥有一个内部可以访问的属性[[prototype]], __proto__
就是浏览器对这个属性的实现, 这个属性指向了Person构造函数的原型对象prototype, 其中sayName方法是定义在原型对象上的, 意味着构造出来的实例都拥有sayName这个方法, prototype里还有一个属性constructor, 这个属性指向了构造函数Person
-
上例中,对象 p可以这样调用 p.toString()。toString是哪里来的? 画出原型图?并解释什么是原型链。
首先, 先解释一下原型链, JS是门面向对象的语言, 而面向对象的语言都有一个标志, 就是类, 通过类可以创建多个具有相同属性和方法的对象, 但是JS中没有类, JS中通过原型链实现继承, 在构造函数创建实例的时候, 实例对象内部的__proto__
会指向构造函数的原型对象prototype, 通过这种方式, 实例就可以访问到原型对象上的属性和方法, 而__proto__
是所有对象内部都存在的属性, 所以原型对象内部也存在__proto__
, 指向的是构造函数的prototype, 在上面的例子中就指向Object.prototype, 那么就可以访问到上面的toStringd, valueOf等方法 对String做扩展,实现如下方式获取字符串中频率最高的字符
String.prototype.getMostOften = function(){
var str = this.toString()
var lengthArr = []
for (var i = 0; i < this.length; i++) {
var r = new RegExp(this[i],'g')
lengthArr.push(str.match(r).length)
}
var maxLength = Math.max.apply(null,lengthArr)
var index = lengthArr.indexOf(maxLength)
return this[index]
}
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因为d 出现了5次
- instanceof有什么作用?内部逻辑是如何实现的?
instanceof可以判断一个对象是否是一个构造函数的实例, 内部通过递归判断对象的__proto__
是否等于构造函数的原型来实现
function instanceOf(obj,func) {
var proto = obj.__proto__
if(proto === func.prototype) {
return true
} else {
if (proto.__proto__) {
return instanceOf(proto,func)
} else {
return false
}
}
}
instanceOf([],Object)//测试, 返回true
instanceOf([],String)//测试, 返回false