前端笔记—从入门到坟墓[js][原型链解读][3]

前端笔记—从入门到坟墓[js][new 与object.create()原理][4]
前端笔记—从入门到坟墓[js][原型链解读][3]
前端笔记—从入门到坟墓[js][闭包][2]
前端笔记—从入门到坟墓[js][作用域与上下文][1]

原型链结构图(重点)

仔细观察图会发现,有几个出现频率比较高的词:
__proto__ : 指向该对象的隐式原型对象,即[[prototype]],通常也就是所谓的该对象原型链的起点
prototype :指向该对象的显式原型对象(只有函数拥有)
constructer:指向该对象的构造器(这个属性属于一个函数的显式原型对象的属性,用于指向该函数,就是在指回去)

在这里插入图片描述

关系归纳

由上图可知很多信息,需要仔细观察上图。

普通对象
      var foo={};//字面量方式定义对象
      foo.__proto__===Object.prototype;//true

注:字面量方式定义对象,其隐式原型指向Object的显式原型,所以foo可以直接调用Object.prototype下的任意方法

函数对象
      function foo2(){};
      foo2.prototype.c = '1'
      foo2.__proto__===Function.prototype;//ture
      foo2.__proto__.__proto__===Object.prototype;//ture

foo2类似于图中Person对象的位置,它是Function的实例。所以其隐式原型指向Function的显示原型。

实例对象
      //实例对象
      var foo3 = new foo2()
      foo3.__proto__ === foo2.prototype //ture
      foo3.__proto__.__proto__===Object.prototype //ture

foo3 类似于图中per对象的位置,它是Person的实例。

Object
      Object().__proto__ === Object.prototype
      //turn 注: Object()返回普通对象obj,类似于刚刚的第一种情况
      Object.__proto__ === Function.prototype
      //turn 注: Object是Function一个实例
Function
      Function().__proto__=== Function.prototype
      //turn 注: Function()返回函数对象,类似于刚刚的第二种情况
      Function.__proto__ === Function.prototype
      //turn 注: Function有隐式原型,只不过Function的显式原型等于隐式原型。
Array
      Array().__proto__ === Array.prototype//turn
      Array().__proto__.__proto__=== Object.prototype//turn
      Array.__proto__ === Function.prototype//turn

Array在图中没有出现,但是它的位置类似于图中Person对象的位置,它的隐式原型指向Function.prototype,其实例对象([]或new Array或Array())的隐式原型指向Array的显式原型。

Math
      Math.__proto__ === Object.prototype//turn
总结
	  console.dir(Function.__proto__)//Function
      console.dir(Object.__proto__)//Function
      console.dir(String.__proto__)//Function
      console.dir(Array.__proto__)//Function
      console.dir(Number.__proto__)//Function
      console.dir(Date.__proto__)//Function
      console.dir(Math.__proto__)//Object
常用api
for in

遍历所有可枚举属性(包含原型链的属性)

      var F = function(){
        this.a = '1'
      }
      F.prototype.b = '2'
      var f = new F()
      f.c = '3'
      for(var i in f){
        console.log(f[i])//1,3,2,
        //涉及到原型链的问题,顺序是:132,因为最先查找自身属性(a,c),再去查找原型链属性(b)
      }
hasOwnProperty()

检测一个对象是否含有特定的自身属性(原型链上的不算)

	  var F = function(){
        this.a = '1'
      }
      F.prototype.b = '2'
      var f = new F()
      f.c = '3'
      for(var i in f){
        if(f.hasOwnProperty(i)){
          console.log(f[i])//1,3
        }
      }
isPrototypeOf()

一个对象是否在另一个对象的原型链上

      function Parent(){}
      Object.prototype.isPrototypeOf(Parent)//true
instanceof

一个对象的原型链上是否有另一个对象的显示原型(.prototype)

也可以说:一个对象是否是另一个对象的实例

console.log(Parent instanceof Object) //true
Object.getPrototypeOf()

返回[[Prototype]]指定对象的原型

console.dir(Object.getPrototypeOf(Parent))//Object.prototype
console.dir(Parent.__proto__)//效果同上
Object.setPrototypeOf()

设置[[Prototype]]指定对象的原型

Object.getPrototypeOf(Parent,Object.prototype)//等于Parent.__proto__ = Object.prototype
判断变量类型

判断:对象,数组,函数,布尔,字符串,数字等常用类型。
介绍几个常用判断方法

    //判断变量类型
    ///测试用例
    var a = {a:1}
    var b = 1
    var c = '1'
    var d = true
    var e = false
    var f = null
    var g = undefined
    var h = function(){}
    var i = [1,2]


    console.log('判断一个变量就是一个对象')
    function isObj(item){
        return {}.toString.call(item) == '[object Object]'
    }
    function isObj2(item){
        return (item instanceof Object&&
            !(item instanceof Array)&&
            !(item instanceof Function))
    }
    function isObj3(item){ //注:typeof null == ‘object’
        return (typeof item == 'object'&&!Array.isArray(item)&&item!=null)
    }
    console.log('判断一个变量就是一个数组')
    function isArr(arr){
        return Array.isArray(arr)
    }
    function isArr2(arr){
        return arr instanceof Array
    }
    function isArr3(arr){
        return Array.prototype.isPrototypeOf(arr)
    }
    console.log('判断一个变量就是一个函数')
    function isFn(fn){
        return {}.toString.call(fn) == '[object Function]'
    }
    function isFn2(fn){
        return fn instanceof Function
    }
    function isFn3(fn){
        return Function.prototype.isPrototypeOf(fn)
    }
    function isFn4(fn){
        return typeof fn == 'function'
    }
    console.log('判断一个变量就是一个数字')
    function isNum(item){
        return typeof item == 'number'
    }
    console.log('判断一个变量就是一个字符串')
    function isStr(str){
        return typeof str == 'string'
    }
补充:判断两个对象是否相等(不是引用相等)
      function isObjectValueEqual(a, b) {
        console.dir(Object)
        var aProps = Object.getOwnPropertyNames(a);
        //返回所有自身的属性名(包括可枚举属性,不包括Symbol类型属性,原型链的属性)组成的数组
        var bProps = Object.getOwnPropertyNames(b);
        if (aProps.length != bProps.length) {
            return false;
        }
        for (var i = 0; i < aProps.length; i++) {
            var propName = aProps[i];
            if (a[propName] !== b[propName]) {
                return false;
            }
        }
        return true;
      }
Array()与[]、new Array
不同点

Array()和[]和new Array返回结果相同,具体不同在于底层构造上面,可以点开下面连接学习
[]或new Array或Array()区别

//在我们比较相同时这样是不行的
console.log(Array() === [])//false 由于[]和Array()都是对象的范畴,所以指针不同,但本质相同
//需要这样比较
console.log(
Object.prototype.toString.call(Array()),//[object Array]
Object.prototype.toString.call([]),//[object Array]
Object.prototype.toString.call(new Array),//[object Array]
Object.prototype.toString.call(Array))//[object Function] 是一个构造函数,所以是Function
与Array比较,String、Number有哪些不同

与Array()比较,String()和Number()返回值略有不同,Array()返回数组属于对象的范畴,而String()、Number()返回的则是字符串和数字类型。

1,String()和Number()返回值存在栈中
我们知道变量当中可以分为基本类型和引用类型。

基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。
引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。

当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。

console.log(Array() === [])//false
console.log(String() === '')//true
console.log(Number() === 0)//true

不过注意一点是new String()和new Number()都是对象,是引用类型。

2,String()和Number()使用instanceof 与 isPrototypeOf()无法判断原型链

	//instanceof 
    console.log(Object() instanceof Object)//true
    console.log(Array() instanceof Array)//true
    console.log(String() instanceof String)//false
    console.log(Number() instanceof Number)//false
    //isPrototypeOf一个对象是否在另一个对象的原型链上
    console.log(Array.prototype.isPrototypeOf([]))//true
    console.log(String.prototype.isPrototypeOf(''))//false
    console.log(Number.prototype.isPrototypeOf(0))//false

因为instanceof和isPrototypeOf都是用于对象,但是实例后的String和Number已经不属于对象了,所以不能使用。
但是,String()和‘’ 的确可以使用 String.prototype 的方法,说明 String.prototype 在其元素链上。

    console.log(Object.getPrototypeOf(String())) // String
    console.log(String.prototype) // String
    console.log(String.prototype === ''.__proto__)
    //true 证明 ‘’或者String()的原型是String.prototype
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值