文档章节

一个后端眼中的js对象和原型链

trayvon
 trayvon
发布于 2017/10/19 08:30
字数 1029
阅读 22
收藏 0

js对象

js中的类型有:

number,string,boolean,object,undefined,function

所以对象可以这么分类:

  1. 函数对象(function)
  2. 其他对象

所以函数对象可以大声唱我们不一样,既然不一样肯定得有一点不一样的烟火,函数对象的不一样在什么地方呢? 每一个函数对象都有一个prototype属性(Function.prototype除外)

作为一个傻傻的后端的我一直以为每一个对象都有一个prototype属性。每一个对象都有的是一个叫做__proto__的隐藏属性,它指向的就是对象所对应的函数对象的prototype(也就是传说中的原型对象)

后面我们再举例子来说明原型对象,我们先看一下那些是函数对象,方便理解。

那些是函数对象

    function FN() {}
    var FA = function() {}
    var FF = new Function('arg1', 'arg2', 'console.log(arg1 + arg2)');

    FF('a','b');
    console.log('typeof Object:' + typeof Object); //function
    console.log('typeof Object.prototype:' + typeof Object.prototype); //object
    console.log('typeof Function:' + typeof Function); //function
    console.log('typeof Function.prototype:' + typeof Function.prototype); //function
    console.log('typeof FN:' + typeof FN); //function
    console.log('typeof FA:' + typeof FA); //function
    console.log('typeof FF:' + typeof FF); //function

不那么精确的总结一下就是:

  1. 带function关键字的
  2. new Funtion出来的对象
  3. Funtion,Object,Function.prototype对象

这里说一下Function.prototype,因为它又是一个不一样的烟火。因为一般的函数对象的prototype都是普通对象,但是Function.prototype是一个函数对象,并且这个函数对象没有prototype属性。

所有的函数对象的__proto__都指向的是Function.prototype

可以使用:

console.log(Object.getOwnPropertyNames(Function.prototype))

打印一下Function.prototype的属性,会发现都是一下公共函数。

原型链

我们把问题简化来处理,看一个最常见的简化的原型链:

function Person(name, age) {
        this.name = name;
        this.age = age;
        this.hobby = function() {
            return '实例对象hobby';
        }
    }
    Person.hobby = function() {
        return '函数对象hobby';
    }
    Person.prototype.hobby = function(){
        return 'prototype hobby';
    }
    var p1 = new Person("tim",20);
    var p2 = new Person("alice",20);
    console.log(p1.hobby === p2.hobby);//false
    console.log(p1.__proto__ == Person.prototype);//true
    console.log(p2.__proto__ == Person.prototype);//true
    console.log(p1.__proto__ == p2.__proto__);//true
    console.log(p1.__proto__.hobby == p2.__proto__.hobby);//true
    console.log(p1.hobby());//实例对象hobby
    console.log(Person.hobby());//函数对象hobby

从前面介绍的我们知道Person是一个函数对象,既然是一个函数对象,那么Person是有prototype属性的,所以给Person的prototype的属性添加一个hobby属性也是合理的事情了。

Person是一个函数对象,那么说Person是一个对象也是合理的了,给Person添加一个hobby属性也是合理的了。

下面就要看一下关键的new关键字的行为了,我们知道Person是一个函数对象,new一个函数对象,基本上执行的就是属性拷贝,然后把new出来的对象的__proto__指向函数对象的prototype的属性。

所以上面的p1.hobby === p2.hobby是false是因为他们是2个对象中不同的属性,是2个不同的引用。

而p1.proto.hobby == p2.proto.hobby是true是因为这2个都是Person.prototype对象上的属性hobby是同一个引用。

js原型链查找方式就是在当前对象中查找这个属性,如果没有就在__proto__指向的对象中去查找,依次查找到Object.prototype结束,因为Object.prototype.proto == null

下面思考一个问题:如果把上面的:

Person.hobby = function() {
    return '函数对象hobby';
}

去掉会有问题吗?

答案是会有问题,这个问题有点绕,但是记住我们前面总结的,所有的函数对象的__proto__指向的都是Function.prototype

所有如果没有上面的代码Person.hobby()这个调用在Person函数对象中找不到hobby属性,就会在Funtion.prototype对象中找,依次找到Object.prototype,显然是找不到的。

注意原型链,不是在Person.prototype中查找,那不在Person对象的原型链。

© 著作权归作者所有

trayvon
粉丝 16
博文 140
码字总数 212221
作品 1
程序员
私信 提问
一个后端眼中的jQuery的extend方法

概述 我看的是3.1.0版本的,先上一段代码吧,不要版本都不一样那就尴尬了,这段代码看着没有多少,但我相信这基本上是这个世界上执行的最多的代码了,再不济也是一个之一。 直接看代码有一点...

trayvon
2017/10/20
24
0
或许我们在 JavaScript 中不需要 this 和 class

今年年初 Douglas Crockford 的新书 How JavaScript Works 出版不久后,我买来看了。在 JavaScript: The Good Parts 出版后 10 年,并深远影响了 JavaScript 语言之后,Douglas Crockford 对...

serialcoder
03/21
0
0
图解javascript原型链

作者: HerryLo 本文永久有效链接: https://github.com/AttemptWeb...... 原型链和原型对象是js的核心,js以原型链的形式,保证函数或对象中的方法、属性可以让向下传递,按照面向对象的说法,...

HerryLo
09/06
0
0
简单理解JavaScript原型链

简单三连 什么是原型 ? 我是这样理解的:每一个JavaScript对象在创建的时候就会与之关联另外一个特殊的对象,这个对象就是我们常说的原型对象,每一个对象都会从原型“继承”属性和方法。 什么...

森林小猎人
05/07
0
0
关于javascript的原型和原型链,看我就够了(一)

关于js的原型和原型链,有人觉得这是很头疼的一块知识点,其实不然,它很基础,不信,往下看 要了解原型和原型链,我们得先从对象说起 创建对象 创建对象的三种方式: 对象直接量 通过对象直...

陌上寒
2018/11/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

搭建高可用MongoDB集群(分片)

搭建高可用MongoDB集群(分片) MongoDB基础请参考:https://blog.51cto.com/kaliarch/2044423 MongoDB(replica set)请参考:https://blog.51cto.com/kaliarch/2044618 一、概述 1.1 背景 ......

linjin200
18分钟前
4
0
CDH6.0.1集成tez-0.9.1计算引擎

参考文章: https://www.jianshu.com/p/9fb9f32e1f0f https://www.baidu.com/link?url=OgpwasnZi7H1dySN2T111sseEWDBaCCTC3DFV61G7756YbrkJCA8Y3UFaueyqnfN&wd=&eqid=daeb8b3500049cf3000000......

Sheav
20分钟前
4
0
Vue内置指令的使用

v-model(数据绑定) v-model常用于表单数据的双向绑定,它本质上是一个语法糖。它主要的有两种应用: 在文本框、多行文本、input的下拉框、单选按钮、复选框中的应用 <div id="app"> ...

凌兮洛
21分钟前
5
0
外部来源应用检查-烦死了,终于找到解决设置了

Android 连接usb调试应用的时候: 华为关闭方法:1、设置-安全-更多安全设置,关掉外部来源应用检查。2、设置-系统-开发人员选项-关闭“监控ADB安装应用” 不知道OPPO 怎么关闭的?...

QGlaunch
22分钟前
4
0
6个K8s日志系统建设中的典型问题,你遇到过几个?

作者 | 元乙 阿里云日志服务数据采集客户端负责人,目前采集客户端 logtail 在集团百万规模部署,每天采集上万应用数 PB 数据,经历多次双 11、双 12 考验。 导读:随着 K8s 不断更新迭代,使...

阿里云官方博客
24分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部