JS---原型,原型链,call/apply 笔记
原型:
定义:原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先,通过该构造函数产生的对象,可以继承该原型的属性和方法,原型也是对象
通俗的讲:原型是构造函数对象的祖先,并且构造函数出的对象,可以继承原型里的属性和方法
如果构造函数的对象与原型有同样的属性,则用自身的属性
原型的特点:
1.利用原型特点和概念,可以提取共有属性,通俗讲:就是把不需要选配的属性,可以放在原型里
原型的增,删,改,查
1.查看原型的属性
Person.prototype.lastName();
2.修改原型的属性
Person.prototype.lastName("ren");
3.增加原型的属性
Person.prototype.age = 40;
4.删除原型的属性
delete Person.prototype.lastName
person.constructor (constructor)构造器的意思
会返回构造对象的构造函数
constructor 是继承来的,指的就是person这个构造对象,如果遇到当person找不到时,就可以通过constructor 来找
没有定义的时候,是系统自带的,所以会显示浅粉色
__proto__ 的作用:就是将构造的对象与原型相连接
例子:
解释下图的例子,因为由于__proto__连接的是原型,但是下图的例子里,将__proto__指向了obj,所有person对象的name属性不会再去找原型里的name (abc) ,而是去找obj里的name (sunny)
通俗讲:就是给构造函数的对象person,换了个祖先
例子:
解释下图的例子,代码实际是执行了红框里的步骤
虽然通过,以下代码看似给原型的name属性换了个值,其实是把原型的房间都给换了
Person.prototype = {
name : 'cherry'
}
Person.prototype.name = 'cherry' 跟这个是不一样的,因为这个是换了属性的值,而上面那种写法,房间都给换了
所以下面的代码返回还是(sunny)
Person.prototype = {
name : 'cherry'
}
如果这段代码 放到var person = new Person(); 上面时,结果就不一样了,因为函数提升后,更改原型房间后的值会把原来的原型覆盖了,所以会返回结果cherry
原型链
上面的这个例子就是个原型链,因为如果调用Son对象的name属性,Son对象里没有,就会从他的父级father对象里找
注意:最上面的Grand也不是最终的__proto__,他的上面还有一个
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就是指向谁
这个是更加灵活的创建对象的一种方法
//var obj = Object.create(原型);
var obj = {name : "sunny", age : 123};
var obj1 = Object.create(obj);
//全部对象的最终都会继承Object.prototype,这句话是错误的,因为有特例,Object.create 就不是
解释:数字想要调用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是自己重写过的
重写:原型上有这个方法,自己又写了不同功能,同一个名字的方法,叫重写
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显示的东西没什么用,所有他的子孙们要重写这个方法
其实上图的例子中,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.第二个用法:
使用call之后,就会改变this指向
使对象里的 this.name = name 变为 obj.name = name
Person.call(obj, 'cheng', 300) 这里括号里第一个参数必须是改变this指向后的值,后面才是要传的参数
//call 需要把实参按照形参的个数传进去
//apply 需要传一个arguments
所以他们只是传参形式不同
apply
本文地址:https://blog.csdn.net/weixin_42641193/article/details/107366905
推荐阅读
-
JS学习笔记之原型链和利用原型实现继承详解
-
JS学习笔记之原型链和利用原型实现继承详解
-
javascript基于原型链的继承及call和apply函数用法分析
-
前端笔记知识点整合之JavaScript面向对象(一)Object&函数上下文&构造函数&原型链
-
前端综合学习笔记---变量类型、原型链、作用域和闭包
-
JS---原型,原型链,call/apply 笔记
-
javascript基于原型链的继承及call和apply函数用法分析
-
javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式_基础知识
-
Javascript学习笔记7 原型链的原理_基础知识
-
JavaScript学习笔记(二十二)——原型及原型链