欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JS---原型,原型链,call/apply 笔记

程序员文章站 2022-03-11 16:22:14
原型:定义,原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先,通过该构造函数产生的对象,可以继承该原型的属性和方法,原型也是对象通俗的讲:原型是构造函数对象的祖先,并且构造函数出的对象,可以继承原型里的属性和方法......

JS---原型,原型链,call/apply 笔记

原型:

定义:原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先,通过该构造函数产生的对象,可以继承该原型的属性和方法,原型也是对象

通俗的讲:原型是构造函数对象的祖先,并且构造函数出的对象,可以继承原型里的属性和方法

如果构造函数的对象与原型有同样的属性,则用自身的属性

原型的特点:

1.利用原型特点和概念,可以提取共有属性,通俗讲:就是把不需要选配的属性,可以放在原型里

 

 

原型的增,删,改,查

1.查看原型的属性

Person.prototype.lastName();

2.修改原型的属性

Person.prototype.lastName("ren");

3.增加原型的属性

Person.prototype.age = 40;

4.删除原型的属性

delete Person.prototype.lastName

JS---原型,原型链,call/apply 笔记

 

person.constructor  (constructor)构造器的意思

会返回构造对象的构造函数

constructor 是继承来的,指的就是person这个构造对象,如果遇到当person找不到时,就可以通过constructor 来找

JS---原型,原型链,call/apply 笔记

没有定义的时候,是系统自带的,所以会显示浅粉色

 

__proto__ 的作用:就是将构造的对象与原型相连接

JS---原型,原型链,call/apply 笔记

 

例子:

解释下图的例子,因为由于__proto__连接的是原型,但是下图的例子里,将__proto__指向了obj,所有person对象的name属性不会再去找原型里的name (abc) ,而是去找obj里的name (sunny)

通俗讲:就是给构造函数的对象person,换了个祖先

JS---原型,原型链,call/apply 笔记

 

 

例子:

解释下图的例子,代码实际是执行了红框里的步骤

虽然通过,以下代码看似给原型的name属性换了个值,其实是把原型的房间都给换了

Person.prototype = {
            name : 'cherry'
        }

Person.prototype.name = 'cherry' 跟这个是不一样的,因为这个是换了属性的值,而上面那种写法,房间都给换了

所以下面的代码返回还是(sunny)

JS---原型,原型链,call/apply 笔记

Person.prototype = {
            name : 'cherry'
        }

如果这段代码 放到var person = new Person(); 上面时,结果就不一样了,因为函数提升后,更改原型房间后的值会把原来的原型覆盖了,所以会返回结果cherry

 

原型链

JS---原型,原型链,call/apply 笔记

上面的这个例子就是个原型链,因为如果调用Son对象的name属性,Son对象里没有,就会从他的父级father对象里找

注意:最上面的Grand也不是最终的__proto__,他的上面还有一个

JS---原型,原型链,call/apply 笔记

Grand.prototype.__proto__ = Object.prototype 这个是所有对象的最终原型

 

原型链上的增,删,改,查

原型链的查:

Father.prototype.lastName

原型链的增:

Father.prototype.age = 40

son.fortune.card2 = 'master' (这种是调用的修改,这种只能改引用值,原始值是不行的)

原型链的删:

delete Father.prototype.age (只能通过原型来删,不能通过构造的对象来删)

原型链的改:

Father.prototype.age = 30

 

//a.sayName() sayName里面的this指向是,谁调用的这个方法,this就是指向谁

JS---原型,原型链,call/apply 笔记

 

这个是更加灵活的创建对象的一种方法

//var obj = Object.create(原型);

 var obj = {name : "sunny", age : 123};
 var obj1 = Object.create(obj);

JS---原型,原型链,call/apply 笔记

 

//全部对象的最终都会继承Object.prototype,这句话是错误的,因为有特例,Object.create 就不是

 

JS---原型,原型链,call/apply 笔记

解释:数字想要调用tostring方法,他是不能直接调用的,

必须要经过一个包装类的操作 new Number(num).toString();

而 new Number的原型是:

          Number.prototype.toString

但是Number.prototype也有一个原型,他的原型是:

           Number.prototype.__proto__ = Object.prototype

所以以上的操作就形成了一个原型链

注意:由于Number.prototype 上有tostring这个方法,所以就不需要用*原型 Object.prototype 上的tostring方法

所以Number调用的tostring是自己重写过的

重写:原型上有这个方法,自己又写了不同功能,同一个名字的方法,叫重写

 

JS---原型,原型链,call/apply 笔记

toString 这里的方法,重写后就相当于覆盖了原型了的toString方法

 

不但这些方法可以人为的重写,电脑自己也会重写

       //Object.prototype.toString
        
        //Number.prototype.toString
        //Array.prototype.toString
        //Boolean.prototype.toString
        //String.prototype.toString

 

如果直接调用Object.prototype.toString

Object.prototype.toString.call(123)
就会出现这个结果:  "[object Number]"

真正顶端的toString显示的东西没什么用,所有他的子孙们要重写这个方法

 

JS---原型,原型链,call/apply 笔记

其实上图的例子中,document.write() 打印的是obj.tostring 所以最后会输出aaa

 

由于javascript里的小数会有bug而且是无法修复的,所以在javascript里尽量避免使用小数,因为使用小数不精准

javascript之前只可以操作小数点后15,现在由于浏览器升级了,就没有限制了

js不处理数据,数据一般都是后端来处理的

//可正常计算的范围         小数点前16位,后16位

 

所以会采用一个办法,取整,向上取整(Math.ceil()),向下取整(Math.floor)

Math.ceil(123.234)
124

Math.floor(123.999)
123

 

 

 

call/apply (这个知识点非常的小,但是非常的常用)

作用:改变this指向

1.第一个用法:

function test() {

        }

    test() --->  test.call();  //这里执行test()  就是执行的test.call()

2.第二个用法:

JS---原型,原型链,call/apply 笔记

使用call之后,就会改变this指向

使对象里的 this.name = name  变为 obj.name = name

Person.call(obj, 'cheng', 300)  这里括号里第一个参数必须是改变this指向后的值,后面才是要传的参数

 

//call 需要把实参按照形参的个数传进去

//apply 需要传一个arguments

所以他们只是传参形式不同

JS---原型,原型链,call/apply 笔记

 

apply

JS---原型,原型链,call/apply 笔记

 

本文地址:https://blog.csdn.net/weixin_42641193/article/details/107366905

相关标签: javascript