温故而知新篇之《JavaScript忍者秘籍(第二版)》学习总结(二)——函数进阶篇

前言

这本书的电子版我已经在学习总结第一篇已经放了下载链接了,可以去查看
温故而,知新篇之《JavaScript忍者秘籍(第二版)学习总结(一)——函数篇

最近看了一句话,觉得挺不错的,分享下:

“不要把自己的努力看的太重,你自己觉得做这个很努力,做那个很努力;当你奔跑、跌倒的同时,有人比你已经先站起来跑了。
其实,努力应该是生活的常态,不应该被认为是稀缺、可贵的品质
而不是说 你努力了,你就应该和别人在很多事情上不一样。你应该不断的提升自己才是努力的意义。

我简直了,文邹邹的~~~哈哈哈哈。
来来来,说正题


arguments参数

arguments对象有一个名为length的属性,表示实参的确切个数。通过数组索引的方式可以获取单个参数的值,例如,arguments[2]将获取第三个参数

function(a,b,c){
//arguments[0]=a
//arguments[1]=b
console.log(arguments[2] === c) // true
}

你可能会被它的用法误导,毕竟它有length属性,而且可以通过数组下标的方式访问到每一个元素。但它并非JavaScript数组,如果你尝试在arguments对象上使用数组的方法(例如,上一章中用到的sort方法),会发现最终会报错。arguments对象仅是一个类数组的结构,在使用中要尤为注意。

arguments对象作为函数参数的别名

function infiltrate(person) {
 arguments[0] = 'ninja';
 person === 'ninja' // true
 
 //同理
 person = 'gardener';
 arguments[0] === 'gardener' // true
}

注意⚠️:

严格模式避免使用arguments别名

"use strict";  ⇽--- 开启严格模式
function infiltrate(person) {
    arguments[0] = 'ninja';  ⇽--- 改变第一个参数”
    arguments[0] === 'ninja' // true
    person === 'gardener' // false

}

this参数:函数上下文

函数调用

我们可以通过4种方式调用一个函数,每种方式之间有一些细微差别。
  • 作为一个函数(function)——skulk(),直接被调用。
  • 作为一个方法(method)——ninja.skulk(),关联在一个对象上,实现面向对象编程。
  • 作为一个构造函数(constructor)——new Ninja(),实例化一个新的对象。
  • 通过函数的apply或者call方法——skulk.apply(ninja)或者skulk.call(ninja)。

这里要补充下,书中有说,作为函数直接被调用、作为方法被调用
这段内容,我当时在理解的时候,以为自己理解了。后来做了几道题才明白这个意思。

var a=10
function b(){
  console.log(a) // 10 // 当前语义环境
  console.log(this.a) // 20  执时环境
}

var c={
  a:20,
  ninja:b
}
console.log(c.ninja())

注意⚠️:

上面的例子中,b不是c的一个方法,b是一个独立的函数。
当通过方法饮用去调用函数时,c.ninja(),对函数调用时,上下文就是c;

this,
当直接通过函数名调用,也就是将函数作为函数调用时,因为是在非严格模式下执行,因此预期的函数上下文结果应当是全局上下文(window)

作为构造函数调用

function Ninja() {
 this.skulk = function() {
   return this;
 };
}  ⇽--- 构造函数创建一个对象,并在该对象也就是函数上下文上添加一个属性skulk。这个skulk方法再次返回函数上下文,从而能让我们在函数外部检测函数上下文

var ninja1 = new Ninja();
var ninja2 = new Ninja();  ⇽--- 通过关键字new调用构造函数创建两个新对象,变量ninja1和变量ninja2分别引用了这两个新对象

console.log(ninja1.skulk() === ninja1,
 "The 1st ninja is skulking");
console.log(ninja2.skulk() === ninja2,
 "The 2nd ninja is skulking");  ⇽--- 检测已创建对象中的skulk方法。每个方法都应该返回自身已创建的对象 

当使用关键字new调用函数时,会创建一个空的对象实例并将其设置为构造函数的上下文(this参数)

注意⚠️:

面试的时候总是会问到。
一般来讲,当调用构造函数时会发生一系列特殊的操作
使用关键字new调用函数会触发以下几个动作。

1.创建一个新的空对象。
2.该对象作为this参数传递给构造函数,从而成为构造函数的函数上下文。
3.新构造的对象作为new运算符的返回值(除了我们很快要提到的情况之外)。
image

构造函数的返回值

  • 如果构造函数返回一个对象,则该对象将作为整个表达式的值返回,而传入构造函数的this将被丢弃。
  • 但是,如果构造函数返回的是非对象类型,则忽略返回值,返回新创建的对象。

箭头函数 this

var Button={
  clicked:false,
  click:()=>{
    this.clicked = true;
    console.log(this) // window
  }
}
Button.click()
function Button(){
  clicked=false
  click=()=>{
    this.clicked = true;
    console.log(this) // window
  }
}
Button()
click()

注意⚠️:

由于this值是在箭头函数创建时确定的
`在全局代码中定义对象字面量,在字面量中定义箭头函数,那么箭头函数内的this指向全局window对象`

小结:

  • 当调用函数时,除了传入在函数定义中显式声明的参数之外,同时还传入两个隐式参数:arguments与this
arguments参数是传入函数的所有参数的集合。具有length属性,表示传入参数的个数,通过arguments参数还可获取那些与函数形参不匹配的参数。在非严格模式下,arguments对象是函数参数的别名,修改arguments对象会修改函数实参,可以通过严格模式避免修改函数实参。
this表示函数上下文,即与函数调用相关联的对象。函数的定义方式和调用方式决定了this的取值。
  • 函数的调用方式有4种。
作为函数调用:skulk()。
作为方法调用:ninja.skulk()。
作为构造函数调用:new Ninja()。
通过apply与call方法调用:skulk.apply(ninja)或skulk.call(ninja)。
  • 函数的调用方式影响this的取值。
如果作为函数调用,在非严格模式下,this指向全局window对象;在严格模式下,this指向undefined。
作为方法调用,this通常指向调用的对象。
作为构造函数调用,this指向新创建的对象。
通过call或apply调用,this指向call或apply的第一个参数。
  • 箭头函数没有单独的this值,this在箭头函数创建时确定。
  • 所有函数均可使用bind方法,创建新函数,并绑定到bind方法传入的参数上。被绑定的函数与原始函数具有一致的行为。

摘录来自: [美] John Resig Bear Bibeault Josip Maras. “JavaScript忍者秘籍(第2版)。” iBooks.

没比别人多什么天赋;只有努力💪、用心、重复

23 声望
9 粉丝
0 条评论
推荐阅读
前端性能指标的介绍
前言被问到优化性能的方式有哪些,会被提到合并文件,压缩资源等,但是对于性能的衡量标准,各执一词;衡量标准有很多,本文讲介绍最具有代表性,使用最广泛的几种性能代表。

哦哈哈阅读 263

从零搭建 Node.js 企业级 Web 服务器(零):静态服务
过去 5 年,我前后在菜鸟网络和蚂蚁金服做开发工作,一方面支撑业务团队开发各类业务系统,另一方面在自己的技术团队做基础技术建设。期间借着 Node.js 的锋芒做了不少 Web 系统,有的至今生气蓬勃、有的早已夭折...

乌柏木148阅读 12.1k评论 10

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy46阅读 5.9k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木65阅读 6.1k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs39阅读 6.3k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木42阅读 7.3k评论 6

从零搭建 Node.js 企业级 Web 服务器(二):校验
校验就是对输入条件的约束,避免无效的输入引起异常。Web 系统的用户输入主要为编辑与提交各类表单,一方面校验要做在编辑表单字段与提交的时候,另一方面接收表单的接口也要做足校验行为,通过前后端共同控制输...

乌柏木33阅读 6.1k评论 9

没比别人多什么天赋;只有努力💪、用心、重复

23 声望
9 粉丝
宣传栏