10分钟让你完全读懂js中的原型,原型链

构造函数

之前写过一次这个内容,但是过来复习这方面知识的时候感觉写的不好,所以决定在写一次来复习一下。但是看了好几篇文章。是每个人说的风格都不太一样。知识点的起点都不太一样。所以我觉得都简单提一下。
先看一下构造函数的创建方式

		function obj(name){
            this.name = name;
        }
        obj.add = (x,y) =>{
			return x+y
		}
        var Person = new obj('lly');
        console.log(Person.name)
        console.log(Person.name)

上面的代码中 obj就是一个构造函数,通过new的方式创建了一个对象。
还有俩个知识点需要了解一下。实例成员静态成员
实例成员:是构造函数的内部通过this添加的属性,我们把他叫做实例成员。实例成员只能通过new创建对象的方式去访问。
静态成员:是构造函数在外部添加的属性,我们叫静态成员;静态成员不能通过new的方式去访问,但是可以直接通过构造函数去调用
看代码

		function obj(name){
            this.name = name;  //实例成员
        }
        obj.age = 20;   //静态成员 
        let o = new obj('cyd');
        console.log(o.age)  //undefind
        console.log(o.name) // cyd
        console.log(obj.name) //obj
        console.log(obj.age) //20

这里有一点需要我们注意的是实例成员直接构造函数访问的时候,返回构造函数的名称。上代码中obj。

javascript原型

在开始说之前,先把几个关键的点说一下。记住好方便后面理解
prototype :这个只有函数才会有的属性,称之为原型。后面的继承也是需要它。
proto:对象中会有的属性指向原型,函数中也有,因为函数也是一个对象。
constructor构造函数,为啥说叫构造函数那,因为通过它可以获取构造函数
上面我们就先简单记一下这几个关键字。下面我们在详细的说明一下。

prototype

我们看下面的代码

		function obj(name){
            this.name = name;
        }
        obj.prototype.printName = function(x,y){
            return x+y
        }
        var Person = new obj('lly');
       console.log(obj.prototype)
       //打印如下图

在这里插入图片描述
之前说到prototype说是原型,why?因为他指向的原型,我们通过obj.prototype获得的就是原型,而原型是一个对象展示出来的。
上面的代码中有一句obj.prototype.printName这句,这个的意思就是在原型上增加一个printName方法所以在下面打印的原型上会看到printName这个方法。
那我们接着看这个原型上还有俩个其他的属性。constructor和__proto__这里为了对应上面的顺序,就先说__proto__。

proto

上面我们说过,它会是对象都会有的一个属性。在对象访问这个属性的时候指向是原型对象,小二上代码。

		function obj(name){
            this.name = name;
        }
        obj.prototype.printName = function(x,y){
            return x+y
        }
        let o = new obj('cyd');
        console.log(o.__proto__)

在这里插入图片描述
一模一样啊,这就证实了__proto__这个也指向原型对象。那就可以的出一个结果

console.log(o.__proto__ == obj.prototype)   //true

constructor

上面我们说过constructor是构造函数。why?小二上代码

		function obj(name){
            this.name = name;
        }
        obj.prototype.printName = function(x,y){
            return x+y
        }
        let o = new obj('cyd');
        console.log(o.__proto__.constructor)
        console.log(obj.prototype.constructor)
        //结果如下

在这里插入图片描述
看到这我们就明白了吧,为啥叫构造函数,因为用原型对象去访问constructor我们又可以获得其构造函数obj。所以我们叫他构造函数。我们又的到一个结果

		console.log(o.__proto__.constructor == obj)  //true
        console.log(obj.prototype.constructor == obj) //true

问我们上面还说过,函数也是可以访问__proto__那函数去直接访问没啥实际意义,就不做讨论了。

原型链

理解了上面的内容,在理解原型链就很简单了。我们可以知道的是每一个对象都有一个__proto__,而我们的原型也是一个对象,那原型对象的__proto__是指向什么地方的那。小二上代码

		function obj(name){
            this.name = name;
        }
        obj.prototype.printName = function(x,y){
            return x+y
        }
        let o = new obj('cyd');
        console.log(o.__proto__.__proto__)
        console.log(o.__proto__.__proto__.constructor)

在这里插入图片描述
哦嘛噶,返回的还是一个原型对象,构造函数是Object(这边说明一下,Object是根本原型对象,所有我们访问的一些对象方法都来源这边,比如object.create、assign等)就像是我们没有创建这个方法但是我们却能访问的到。
我们先接着看这个Object的原型对象的__proto__是什么东西。

  console.log(o.__proto__.__proto__.__proto__) // null

null空。原来Object就是就是原型的老大了。上面没有比他更大的了。所以我们去找的时候只能是null了。这样一层一层的去找就形成了原型链。
看图
在这里插入图片描述

小剧场:
一个三代之家,小明想要一个苹果,他就去找他爸爸要,但是爸爸没有,他就向他的爸爸的爸爸要。结果他爸爸的爸爸有,也就是他爷爷有一个苹果,就给他了。

对象其他知识点

继承
上面说到,prototype可以用来继承。到底是怎么继承的那。小二上代码

		function obj(name){
            this.name = name;
            this.add = function(x,y){
                return x+y
            }
        }
        obj.prototype.product = function(x,y){
            return x*y
        }
        function obj2(age,name){
            obj.call(this,name);
            this.age = age
        }

        let a = new obj('lly');
        let b = new obj2(20,'cyd');
        console.log(a.name)   //lly
        console.log(b.name)   // cyd
        console.log(b.add(5,5))  //10
        console.log(b.product(2,5))   //Uncaught TypeError: b.product is not a function 

上面代码中我们使用call实现了实例成员的继承。但是看到原型上的就没办法进行继承。那原型对象上的怎么可以进行继承那。我们上面说过prototype继承需要它,那我们试一下。

	function obj(name){
            this.name = name;
            this.add = function(x,y){
                return x+y
            }
        }
        obj.prototype.product = function(x,y){
            return x*y
        }
        function obj2(age,name){
            obj.call(this,name);
            this.age = age
        }
        
        obj2.prototype = Object.create(obj.prototype);
        obj2.prototype.ls = function(x){
            return x
        }
        let a = new obj('lly');
        let b = new obj2(20,'cyd');
        console.log(a.name) //lly
        console.log(b.name) //cyd
        console.log(b.add(5,5))  // 10
        console.log(b.ls(3))    // 3
        console.log(b.product(2,5))  //10

只要加上一句 **obj2.prototype = obj.prototype;**就可以实现原型的继承。
说了这么多都还是es5,下面说说es6吧
es6就引入了类的概念。class 。先看一下使用方法吧。小二上代码

 		class obj{
            constructor(name){
                this.name = name
            }
            add(x,y){
                return x+y
            }
        }
        let a = new obj('lly');
        console.log(a.name) //lly
        console.log(a.add(5,2)) // 7

上面就是class基本的使用。class必须使用new的方式去使用。类中的方法全部都是放在原型上。
可以打印出来看一下

		class obj{
            constructor(name){
                this.name = name
            }
            add(x,y){
                return x+y
            }
        }
        let a = new obj('lly');
        let b = new obj('cyd');
        console.log(a.__proto__ == b.__proto__)  //true

Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。

	lass obj{
            constructor(name){
                this.name = name
            }
            add(x,y){
                return x+y
            }
        }
        class obj2 extends obj{ }
        let p = new obj2('cyd');
        console.log(p.name)  // cyd

总结

不好意思没有总结,总结的事交给你了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值