JavaScript基础知识5点(2019.1.2)
1、如题
function Person(name) {
this.name = name
return name;
}
let p = new Person('Tom');
实例化 Person 过程中,Person 返回什么(或者 p 等于什么)?
返回 {name:"Tom"}
变化一下:
function Person(name) {
this.name=name
}
let p=new Person("Tom")
console.log(p) //{name:"Tom"}
构造函数不需要显示的返回值。下段代码没有显示写 return,仍会有返回值 {name:'"Tom"}
如果 return 的是对象,则返回该对象
function Person(name) {
this.name = name
return {}
}
let p = new Person('Tom')
实例化 Person 过程中,Person 返回什么(或者 p 等于什么)?
返回 {}
function Person(name) {
this.name=name
return {age:18}
}
let p=new Person("Tom")
console.log(p) //{age: 18}
使用 new 来创建对象(调用构造函数)时,如果 return 的是 非对象(数字、字符串、布尔类型等)会忽略返回值
若 return null 也会忽略返回值
function Person(name) {
this.name=name
return "xxxxx"
}
let p=new Person("Tom")
console.log(p) //{name:"Tom"}
function Person(name) {
this.name=name
return null
}
let p=new Person("Tom")
console.log(p) //{name:"Tom"}
function Person(name) {
// this.name=name
return name
}
let p=Person("Tom")
console.log(p) //'Tom'
function Person(name) {
this.name=name
return name
}
let p=Person("Tom")
console.log(p) //'Tom'
2、typeof 和 instanceof 的区别
(1)typeof:返回数据类型的字符串表达
判断数值,返回 "number"
判断布尔值,返回 "boolean"
判断 undefined,返回 "undefined"
不能用来判断 null 和 object(不能区别,只返回object)
不能用来判断 array 和 object(不能区别,只返回object)
例:
console.log(typeof 123) //"number"
console.log(typeof false) //boolean
console.log(typeof "123") //string
console.log(typeof undefined) //undefined
console.log(typeof function () {}) //function
console.log(typeof null) //object
console.log(typeof [1,2]) //object
console.log(typeof {name:"c"}) //object
(2)instanceof:a instanceof b,判断 对象a 是否是 构造函数b 的实例,即判断 a._ proto _ 是否等于 b.prototype
注意:左侧必须是对象(object),如果不是,直接返回 false
例1:
let string="123"
console.log(string instanceof String) //false
let string=new String('123')
console.log(string instanceof String) //true
console.log(string) //{"123"}
例2:
如果 Student inherit from Person(Student 类继承 Person,需是基于原型的继承),let s = new Student('Lily'),那么 s instanceof Person 返回什么?
function Person (name) {
this.name = name;
}
function Student () { }
Student.prototype = Person.prototype;
Student.prototype.constructor = Student;
let s = new Student('Tom');
console.log(s instanceof Person) // 返回 true
3、new 的内部机制
(1)new
function Person (name) {
this.name = name
this.getName = function () {
return "my name is "+name
}
}
let p =new Person("Tom")
① 创建一个对象 p,同时继承 对象类 Person 的原型(Person.prototype)
② 执行对象类 Person 的构造函数,同时该实例 p 的属性和方法被 this 所引用,即 this 指向新构造的实例 p
③ 如果构造函数 Person return 了一个新的对象,那么该对象会取代 new 出来的结果。
如果构造函数 Person 没有 return ,则会返回 ① 所创建的对象,因为 构造函数 Person 会隐式返回 this
代码描述:
// let p =new Person("Tom")
let p=(function () {
let obj={}
obj._ _proto_ _=Person.prototype
//赋值语句
let result = Person.call(obj,"Tom");
return typeof result === 'object'? result : obj;
})()
console.log(p)
console.log(Person.name) //Person
(2)JS 中万物皆对象,为什么还要通过 new 来产生对象?
因为 new 的意义在于它不仅仅实例化了一个对象,并且还实现了 js 中的继承。
4、instanceof 的内部机制
// x instanceof y
if(x._ _proto_ _===null) return false
while(x._ _proto_ _!==null){
if(x._ _proto_ _===y.prototype){
return true
}
//如果没有进入上面的if,那么x会一直沿着隐式原型链_ _proto_ _向上查找,
//直到找到 x._ _proto_ _._ _proto_ _._ _proto_ _ ...=y.prototype 为止
x._ _proto_ _= x._ _proto_ _._ _proto_ _
}
5、原型和原型链问题
function F() { }
function O() { }
O.prototype=new F()
let obj=new O()
console.log(obj instanceof O) //true
console.log(obj instanceof F) //true
console.log(obj.__proto__ === O.prototype) //true
console.log(obj.__proto__.__proto__ === F.prototype) //true
根据 new 的内部机制改写上面代码:
// let obj=new O()
let obj=(function(){
let a={}
a._ _proto_ _=O.prototype
//因为 O.prototype=new F(),a._ _proto_ _=O.prototype,
//所以 a._ _proto_ _=new F()
//因为 O.prototype=new F(),所以 O.prototype._ _proto_ _=F.prototype
a._ _proto_ _._ _proto_ _=F.prototype
return a
})()
调整顺序后,结果完全不一样
function F() { }
function O() { }
//obj.__proto__=O.prototype
let obj=new O()
//注意:此时修改了O的prototype属性,obj的隐式原型并没有随之修改,而是等于修改前的O.prototype
//O.prototype.__proto__=F.prototype
O.prototype=new F()
//obj.__proto__ === O.prototype false 因为O.prototype已被修改
console.log(obj instanceof O) //false
//obj.__proto__ === F.prototype false 因为 obj.__proto__=修改前的O.prototype,跟 F 已没有关系
console.log(obj instanceof F) //false
//同 obj instanceof O
console.log(obj.__proto__ === O.prototype) //false
//obj,跟 F 已没有关系
console.log(obj.__proto__.__proto__ === F.prototype) //false
(完)