bind返回函数被当成构造函数的情况
在MDN中有这么一句话
1 | bind()中的第一个参数:调用绑定函数时作为 this 参数传递给目标函数的值。 |
那么这句话啥意思呢??
首先,我们都知道bind()会返回一个新的函数,如果这个返回的新的函数作为构造函数创建一个新的对象,那么此时this不再指向传入给bind的第一个参数,而是指向用new创建的实例
1 | function func (name) { |
1 | function func (name) { |
在MDN中有这么一句话
1 | bind()中的第一个参数:调用绑定函数时作为 this 参数传递给目标函数的值。 |
那么这句话啥意思呢??
首先,我们都知道bind()会返回一个新的函数,如果这个返回的新的函数作为构造函数创建一个新的对象,那么此时this不再指向传入给bind的第一个参数,而是指向用new创建的实例
1 | function func (name) { |
1 | function func (name) { |
bind()
方法创建一个新的函数,在 bind()
被调用时,这个新函数的 this
被指定为 bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用
1 | function.bind(thisArg[, arg1[, arg2[, ...]]]) |
this
参数传递给目标函数的值。 如果使用new
运算符构造绑定函数,则忽略该值。当使用 bind
在 setTimeout
中创建一个函数(作为回调提供)时,作为 thisArg
传递的任何原始值都将转换为 object
。如果 bind
函数的参数列表为空,执行作用域的 this
将被视为新函数的 thisArg
。arg1, arg2, ...
返回一个原函数的拷贝,并拥有指定的 this 值和初始参数
Polyfill 是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能。
比如说 polyfill 可以让 IE7 使用 Silverlight 插件来模拟 HTML Canvas 元素的功能,或模拟 CSS 实现 rem 单位的支持,或 text-shadow
,或其他任何你想要的功能
Poly表示可以使用多种技术来解决它-它不仅限于使用JavaScript完成,而且fill会填补浏览器中需要该技术的空白。它也不意味着“旧的浏览器”(因为我们也需要填充新的浏览器)
1 | if (!Function.prototype.bind) { |
==JavaScript 采用的是词法作用域(静态的作用域),函数的作用域在函数定义的时候就决定了==(一个函数先定义后执行,定义的时候什么都不干,但是已经锁定了其词法作用域,执行的时候有执行机上下文,会用到已经定义的词法作用域)
而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的
1 | var value = 1; |
前面我们已经说了,JavaScript采用的是静态作用域,所以这个例子的结果是 1
1 | // 赋值式函数 |
然而去看这段代码:
1 | // 声明式函数 |
可执行代码(executable code)的类型:全局代码、函数代码、eval代码。
举个例子,当执行到一个函数的时候,就会进行准备工作,这里的“准备工作”,让我们用个更专业一点的说法,就叫做”执行上下文(execution context)”。
事实上,JS的解析过程分为两个阶段:预编译期(预处理)与执行期
预编译期JS会对本代码块中的所有声明的变量和函数进行处理(类似与C语言的编译),但需要注意的是此时处理函数的只是声明式函数,而且变量也只是进行了声明但未进行初始化以及赋值
1 | //例子1 |
1 | // 例子2 |
1 | // 例子3 |
1 | //单个函数执行的时候有执行机上下文,多个函数执行的时候有执行上下文栈 |
对于每个执行上下文,都有三个重要属性:
变量对象是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明
全局上下文中的变量对象就是全局对象!
当进入执行上下文时,这时候还没有执行代码,
变量对象会包括:
1 | function foo(a) { |
在进入执行上下文后,这时候的 AO 是
1 | AO = { |
在代码执行阶段,会顺序执行代码,根据代码,修改变量对象的值
还是上面的例子,当代码执行完后,这时候的 AO:
1 | AO = { |
1 | function foo() { |
函数创建时,各自的[[scope]]为:
1 | //scope可以理解为函数在创建时的一个属性 |
详见下面的例子 – 图片中只展示出来了层级关系
1 | function foo() { |
当函数激活时(激活通俗的理解就是执行),进入函数上下文,创建 VO/AO 后,就会将活动对象添加到作用链的前端。
这时候执行上下文的作用域链,我们命名为 ScopeChain
1 | ScopeChain = [AO].concat([[Scope]]); |
至此,作用域链创建完毕
其实很复杂,简单来说是谁调用指向谁
1 | var scope = "global scope"; |
1 | ECStack = [ |
1 | globalContext = { |
1 | checkscope.[[scope]] = [ |
1 | ECStack = [ |
1 | 复制函数 [[scope]] 属性创建作用域链, |
1 | ECStack = [ |
1 | 复制函数 [[scope]] 属性创建作用域链 |
1 | ECStack = [ |
闭包是指那些能够访问自由变量的函数(MDN)、闭包是指有权访问另外一个函数作用域中的变量的函数(红宝书p178)、《JavaScript权威指南》中就讲到:从技术的角度讲,所有的JavaScript函数都是闭包。
从实践角度:以下函数才算是闭包:
1 | var scope = "global scope"; |
这里直接给出简要的执行过程:
了解到这个过程,我们应该思考一个问题,那就是:
当 f 函数执行的时候,checkscope 函数上下文已经被销毁了啊(即从执行上下文栈中被弹出),怎么还会读取到 checkscope 作用域下的 scope 值呢?
我们知道 f 执行上下文维护了一个作用域链:
1 | fContext = { |
call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法
1 | Function.prototype.call2 = function (context) { |
new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象类型之一
1 | function objectFactory() { |
在数学和计算机科学中,柯里化是一种将使用多个参数的一个函数转换成一系列使用一个参数的函数的技术。
1 | //乞丐版:完整版很深 |
1 | function Rectangle(length,width){ |
爸爸的父亲等于妈妈的老公???
bind()创建的function上没有prototype/箭头函数上也没有prototype
事件响应函数在一段时间后才执行,如果在这段时间内再次调用,则重新计算执行时间;当预定的时间内没有再次调用该函数,则执行响应逻辑
underscore中的debounce函数可以防抖
1 | /** |
如果你持续的触发事件,每隔一段时间,只执行一次事件
1 | /** |
1 | /** |
1 | /** |
1 | /** |
创建了一个新的对象,这个对象有着原始对象属性值得精确拷贝,如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
1 | Object.assign(target, ...sources) |
typeof可以用于判断以下js的8种类型:
js的8中数据类型:
但也有缺点 — 暂时性死区(TDZ)
我们知道let和const 具有暂时性死区(即在代码块内,使用let/const命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”)
typeof也具有暂时性死区
1 | typeof x; // ReferenceError -- 声明在后导致出错 |
1 | typeof undeclared_variable // "undefined" -- 若一个变量根本没有声明,倒不会报错 |
1 | // 考烂了的面试题 |
原理: 右边变量的prototype在左边变量的原型链上即可(右边构造函数的原型在不在左边实例的原型链上)
1 | String instanceof String // false |
将一个对象从内存中完整的拷贝出来一份,从内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象
1 | let d = JSON.parse(JSON.stringify(x)) // 将x深拷贝给d |
1 | function deepCopy( obj ){ |
1 | // 面试版本 |
1 | // 测试用例 |
学习自京程一灯董老师课程,如有侵权,联系删除
属性:属性对应的是平常我们书面或交谈时对应的CSS中文称谓,例如height,color等
值:
关键字:如soild,inherit等
泛关键字:可以理解为公交车关键字,就是“所有CSS属性都可以使用的关键字”的意思。
变量:如CSS3中的currentColor等
长度单位:如px,em等(值 + 长度单位 = 长度)
相对长度单位:
1 | h1 { |
绝对长度单位:
功能符:值以函数的形式指定起来的,主要用来表示颜色(rgba和hsla),背景图片地址(url),计算(calc)等,如rfb(0,0,0,.5)、url(‘css-World.png’)等
属性值:属性冒号后面的所有内容
声明:属性名加上属性值就是声明
声明块:用花括号{}包裹的一系列声明
规则或者规则集:出现了选择器,并且后面还跟着声明块
1 | .vo{ |
选择器:
关系选择器
@规则:指的是以@字符开始的一些规则。
1 | .clear::after{ |
1 | <!DOCTYPE html> |
在日常的学习中,我们很多时间需要去从GitHub上寻找一些开源项目
首先,我们需要了解GitHub上面开源项目的一些基本知识:项目名,项目源码,项目描述,Readme.md,star,fork数,更新日期等等
题目:给定一个非负整数数组,你最初位于数组的第一个位置。数组中的每个元素代表你在该位置可以跳跃的最大长度。判断你是否能够到达最后一个位置。
1 | function canJumpyue(position , nums) { |
UEFI启动Windows10+Ubuntu双系统删除Ubuntu方法
安装win10+ubuntu18.04双系统
在Win10与Ubuntu双系统中删除Ubuntu
如有侵权,请联系删除
问题描述
给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 ‘ ? ‘ 和 ‘ * ‘ 的通配符匹配。
‘ ? ‘ 可以匹配任何单个字符。
‘ * ‘ 可以匹配任意字符串(包括空字符串)
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *
代码实现
1 | var star=-1, match=0; |