Javascript收集

JavaScript基础知识5点(2019.1.2)

2019-01-03  本文已影响9人  小进进不将就

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

(完)

上一篇 下一篇

猜你喜欢

热点阅读