首页
友链
壁纸
留言
今日热榜
更多
关于
时光
推荐
精品流量卡
Search
1
都二十多年了,你的梦为什么还没碎!
57,100 阅读
2
2022年5个好用的 BT/ 磁力链接下载工具推荐 |Windows 、安卓系统
37,477 阅读
3
nps内网穿透实现外网访问树莓派
32,440 阅读
4
实践利用宝塔建emlog个人博客-超详细【原创】
26,142 阅读
5
Typecho-Joe-Theme主题帮助文档
24,679 阅读
闲杂乱码
Python
网站源码
微信小程序
娱乐分享
Is相册
软件工具
登录
Search
标签搜索
PHP
HTML
API
Javascript
源码
JS
Vue
Github
CloudFlare
接口
函数
SQL
ASP.NET
MVC
EF
T4模板
后台管理
CDN
微信小程序
MAC
韩小韩
累计撰写
262
篇文章
累计收到
1,307
条评论
首页
栏目
闲杂乱码
Python
网站源码
微信小程序
娱乐分享
Is相册
软件工具
页面
友链
壁纸
留言
今日热榜
关于
时光
推荐
精品流量卡
搜索到
2
篇与
原型
的结果
2022-10-12
原型继承和 Class 继承
⾸先先来讲下 class ,其实在 JS 中并不存在类, class 只是语法糖,本质还是函数class Person {} Person instanceof Function // true组合继承function Parent(value) { this.val = value } Parent.prototype.getValue = function() { console.log(this.val) } function Child(value) { Parent.call(this, value) } Child.prototype = new Parent() const child = new Child(1) child.getValue() // 1 child instanceof Parent // true{callout color="#684def"}以上继承的⽅式核⼼是在⼦类的构造函数中通过 Parent.call(this) 继承⽗类的属性,然后改变⼦类的原型为 new Parent() 来继承⽗类的函数。这种继承⽅式优点在于构造函数可以传参,不会与⽗类引⽤属性共享,可以复⽤⽗类的函数,但是也存在⼀个缺点就是在继承⽗类函数的时候调⽤了⽗类构造函数,导致⼦类的原型上多了不需要的⽗类属性,存在内存上的浪费{/callout}寄⽣组合继承{callout color="#4defb9"}这种继承⽅式对组合继承进⾏了优化,组合继承缺点在于继承⽗类函数时调⽤了构造函数,我们只需要优化掉这点就⾏了{/callout}function Parent(value) { this.val = value } Parent.prototype.getValue = function() { console.log(this.val) } function Child(value) { Parent.call(this, value) } Child.prototype = Object.create(Parent.prototype, { constructor: { value: Child, enumerable: false, writable: true, configurable: true } }) const child = new Child(1) child.getValue() // 1 child instanceof Parent // trueclass继承class Parent { constructor(value) { this.val = value } getValue() { console.log(this.val) } } class Child extends Parent { constructor(value) { super(value) this.val = value } } let child = new Child(1) child.getValue() // 1 child instanceof Parent // true
2022年10月12日
457 阅读
0 评论
0 点赞
2021-06-23
手撸实现 call apply bind 原型函数
{message type="info" content="今天 Joe 老板又给我补课了,他问我call apply bind会用吗,我说会,他又说,把原型函数实现给我写一下,我一下懵逼了,原理,他是来羞辱我的,经过一下午的不懈努力,Joe 老板终于教会了我。"/}实现call{message type="warning" content="call 方法第一个参数是要绑定给this的值,后面传入的是一个参数列表。当第一个参数为null、undefined的时候,默认指向window。"/}{callout color="#f0ad4e"}call传参时,是传入1个或多个参数,所以,需要用...展开{/callout}/* 随便定义一个对象,待会将函数内的this指向指向倒这个对象 */ const obj = { name: '我是需要被绑定改变this指向的对象' } /* 需要改变this指向的函数,没有使用call时,this指向window */ function fn(a, b) { console.log(`This 现在指向 ${this}`); console.log(`传入的 a 是 ${a} ------- b 是 ${b}`); } /* * * 重写call方法 * _this 需要把this改变到哪个目标 * vvhan_com 传递进来的参数 */ Function.prototype.call = function (_this, ...vvhan_com) { /* 创建一个 Symbol call */ const call = Symbol(); /* 给传入的对象 _this 添加call元素为 this(此处this为 fn 函数体) */ _this[call] = this /* 执行 _this对象 中的 call 函数,并传入参数 vvhan_com */ _this[call](...vvhan_com); /* 最后删除 _this对象 中的call元素 */ delete _this[call]; } fn.call(obj, 1,2);实现apply{message type="warning" content="apply接受两个参数,第一个参数是要绑定给this的值,第二个参数是一个参数数组。当第一个参数为null、undefined的时候,默认指向window。"/}{callout color="#f0ad4e"}apply传参时,是传入一个数组,数组里面是参数,所以,不需要用...展开{/callout}/* 随便定义一个对象,待会将函数内的this指向指向倒这个对象 */ const obj = { name: '我是需要被绑定改变this指向的对象' } /* 需要改变this指向的函数,没有使用apply时,this指向window */ function fn(a, b) { console.log(`This 现在指向 ${this}`); console.log(`传入的 a 是 ${a} ------- b 是 ${b}`); } /* * * 重写apply方法 * _this 需要把this改变到哪个目标 * vvhan_com 传递进来的参数 */ Function.prototype.apply = function (_this, vvhan_com) { /* 创建一个 Symbol apply */ const apply = Symbol(); /* 给传入的对象 _this 添加apply元素为 this(此处this为 fn 函数体) */ _this[apply] = this /* 执行 _this对象 中的 apply 函数,并传入参数 vvhan_com */ _this[apply](...vvhan_com); /* 最后删除 _this对象 中的apply元素 */ delete _this[apply]; } fn.apply(obj, [1, 2]);实现bind{message type="warning" content="和call很相似,第一个参数是this的指向,从第二个参数开始是接收的参数列表。区别在于bind方法返回值是函数以及bind接收的参数列表的使用。bind返回值是函数"/}{callout color="#f0ad4e"}因为bind的调用方式,是返回一个新函数,在调用一次,例如:fn.bind(null)(options),所以需要用到高阶函数{/callout}/* 随便定义一个对象,待会将函数内的this指向指向倒这个对象 */ const obj = { name: '我是需要被绑定改变this指向的对象' } /* 需要改变this指向的函数,没有使用bind时,this指向window */ function fn(a, b) { console.log(`This 现在指向 ${this}`); console.log(`传入的 a 是 ${a} ------- b 是 ${b}`); } /* * * 重写bind方法 * _this 需要把this改变到哪个目标 * vvhan_com 传递进来的参数 */ Function.prototype.bind = function (_this, ...vvhan_com) { /* 创建一个 Symbol bind */ const bind = Symbol(); /* 给传入的对象 _this 添加bind元素为 this(此处this为 fn 函数体) */ _this[bind] = this /* 返回函数 并传入参数 这里使用高阶函数接收参数 */ return function (...vvhan_com_) { /* 判断参数传入点 并执行 */ _this[bind](...vvhan_com_.length > 0 ? vvhan_com_ : vvhan_com); /* 最后删除 _this对象 中的bind元素 */ delete _this[bind]; } } fn.bind(obj, 1, 2); fn.bind(obj)(1, 2);最后总结相同点 {callout color="#f0ad4e"}call、apply、bind的作用都是改变函数运行时this的指向,bind返回对应函数=>便于稍后调用; apply, call则是立即调用。{/callout}区别点 {callout color="#f0ad4e"}apply 和 call 的用法几乎相同, 唯一的差别在于:当函数需要传递多个变量时, apply 传入一个数组作为参数输入, call 则是接受一系列的单独变量。{/callout}
2021年06月23日
192 阅读
4 评论
0 点赞