Giter Club home page Giter Club logo

salvation's People

Contributors

sukiey avatar

Watchers

 avatar  avatar

salvation's Issues

【Javascript基础】函数 之 执行上下文

执行上下文

当 javascript 执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)。

代码执行顺序

javascript 引擎在执行代码的时候是按顺序执行的,但是它并非一行一行地分析和执行程序,而是一段一段地分析执行。

而这一段一段的代码便是所谓的可执行代码。

可执行代码

那么,哪些代码可以被称作可执行代码呢?其实,javascript中的可执行代码总共分为三类,分别是:

  • 全局代码
  • 函数代码
  • eval代码

javascript 引擎在遇到以上几类代码时,就会创建对应的执行上下文。

属性

每个执行上下文,都包含以下三个重要属性:

  • 变量对象(Variable Object,VO)
    • 包括 形参、函数声明、变量声明
  • 作用域链(Scope Chain)
    • 由当前作用域的变量对象,以及所有父级作用域的变量对象所构成的链表
  • this

生命周期

一个执行上下文的生命周期可以分为两个阶段,创建阶段和代码执行阶段。

举个栗子:

function foo(a) {
  var b = 2;
  function c() {}
  var d = function() {};

  b = 3;

}

foo(1);
  • 执行上下文创建阶段

​ 该阶段也可以称作【编译阶段】,只不过在 javascript 中编译过程就发生在代码执行前,或者换句话说 javascript 代码是即时编译的。

​ 在该阶段主要是做一些初始化,为进入代码执行阶段做一些准备工作。对于一个函数上下文来说,这些准备工作包括以下几个部分:

​ 1.复制函数 [[scope]] 属性创建作用域链

​ 2.用 arguments 创建活动对象

​ 3.初始化活动对象(Active Object, AO),即加入形参、函数声明、变量声明

​ 活动对象初始化过程会遵循一些原则,具体参见 变量对象初始化过程

​ 4.将活动对象压入函数作用域链顶端。

上面的例子,该阶段的上下文对象为:

Context = {
  AO: {
    arguments: {
      0: 1,
      length: 1
    },
    a: 1,
    b: undefined,
    c: reference to function c(){ },
    d: undefined
  },
  Scope: [AO,  globalContext.VO ],
  this: undefined
}
  • 代码执行阶段

    在代码执行阶段,会顺序执行代码,根据代码,修改变量对象的值。

Context = {
  AO: {
    arguments: {
      0: 1,
      length: 1
    },
    a: 1,
    b: 3,
    c: reference to function c(){ },
    d: reference to FunctionExpression "d"
  },
  Scope: [AO,  globalContext.VO ],
  this: Context.AO
}

变量对象初始化过程

变量对象的初始化过程,是按如下1,2,3,... 的顺序依次进行的。

  1. 函数的所有形参(如果是函数上下文)
    • 由名称和对应值组成的一个变量对象的属性被创建
    • 没有实参,属性值设为undefined
  2. 函数声明
    • 由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建
    • 如果变量对象已存在相同名称的属性,则完全替换这个属性
  3. 变量声明
    • 由名称和对应值(undefined)组成一个变量对象的属性被创建
    • 如果变量名跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性

【Javascript基础】函数 之 作用域

作用域链

可以理解成是由多个执行上下文的变量对象构成的层级链。

变量的查找过程总是沿着作用域链进行。

[[scope]]属性

每一个函数都有一个内部属性 [[scope]]

在定义函数的时候,javascript引擎会把上下文的作用域链赋给函数的内部属性[[scope]]

然后,在执行函数时,进入函数的执行上下文,创建了 VO/AO,就会将活动对象添加到作用域链的顶端。

Scope = [AO].concat([[scope]]);

【Javascript基础】函数 之 arguments对象

arguments对象

简介

  • 它是只定义在函数体中的一个特殊变量
  • 它是一个类数组变量, ArrayLike Object
  • 它维护着传递到这个函数的所有参数和一些其他属性

属性

image

  • 参数列表:上图中类数组的索引属性,name,age,gender
  • length:表示 实参 的个数/长度
  • callee:代表函数自身,可以通过它调用函数自身
    • 在ES5严格模式中该属性被删除了
    • 不要使用 arguments.callee 及它的属性, 它会显著影响现代 js 引擎的性能

参数的自动更新

在非严格模式下,传递给函数的参数值和 arguments 中的值是一一绑定的。

arguments 对象为其内部属性和函数的参数创建了 gettersetter 方法。因此,改变参数的值会同步更新 arguments 对象的值,反之亦然。

P.S. 在严格模式下,它们的值在改变之后互不影响。

传递参数

将参数从一个函数传递到另一个函数。

function a() {
    b.apply(null, arguments);
}
function b() {
    console.log(arguments);
}
a(1,2);

/** output
 * Arguments(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ]
 *   0: 1
 *   1: 2
 *	 callee: ƒ a()
 *	 length: 2
 *	 Symbol(Symbol.iterator): ƒ values()
 *	 __proto__: Object
 *
**/

转数组

var arrayLike = {0: 'name', 1: 'age', 2: 'sex', length: 3 }
// 1. slice
Array.prototype.slice.call(arrayLike)
Array.prototype.slice.apply(arrayLike)
// 2. splice
Array.prototype.splice.call(arrayLike, 0)
// 3. concat
Array.prototype.concat.apply([], arrayLike)
// 4. es6 Array.from
Array.from(arrayLike)

【Javascript基础】数据类型

原始值类型

ECMScript 标准定义了 6 种原始值类型,分别是 布尔值(Boolean)、字符串(String)、数值(Number)、Null、Undefined 和 Symbol(ES6 新引入的)。

  • 原始值类型亦称为 '原始数据类型' 或 '基本数据类型'。
  • 原始值类型的值是 按值访问 的。
  • 它指的是那些保存在 内存中的简单数据。

什么是原始值

  • 原始值只是一种字面量;
  • javascript 引擎会自动把字面量转换成对象,所以可以访问属性和方法。比如:"test".length

原始值类型有哪些

1. boolean

布尔类型。有两个字面量:truefalse。ECMScript 中所有类型都有与这两个布尔值等价的值。

  • true等价的值:非0数字,非空字符串,Object
  • false等价的值:0, 空字符串 "", undefined, null, NaN
// 代码示例
console.log(Boolean(1) === true))
console.log(Boolean("test string") === true)
console.log(Boolean({}) === true)  // true

console.log(Boolean(0) === false)
console.log(Boolean(NaN) === false)
console.log(Boolean("") === false)
console.log(Boolean(undefined) === false)
console.log(Boolean(null) === false) // true

2. string

字符串类型。

区分基本字符串和字符串对象

通常我们定义的都是基本字符串,却可以调用字符串对象才有的属性方法,那是因为 Javascript 引擎会自动将基本字符串转换为字符串对象并且调用相应的方法。

  • 基本字符串
    • 通过引号定义 或者 直接调用String()方法生成的字符串都是基本字符串
  • 字符串对象
    • 通过new String()生成字符串对象实例

长字符串

  • 可以使用+运算符拼接多个字符串
  • 可以在每行末尾使用反斜杠字符\,以指示字符串将在下一行继续,注意反斜杠后面只能紧跟换行符,负责反斜杠将不起作用。
// 代码示例
let test1 = "string";
console.log(test1.length); // 6
console.log("cat".charAt(1)); // "a"

let longString1 =
  "This is a very long string which needs \
to wrap across multiple lines because \
otherwise my code is unreadable.";
let longString2 =
  "This is a very long string which needs " +
  "to wrap across multiple lines because " +
  "otherwise my code is unreadable.";
console.log(longString1 === longString2); // true

3. number

数值类型,包括了整数和浮点数。由于内存限制,ECMScript 并不能保存世界上所有的数值。

数值范围

  • 最大值:Number.MIN_VALUE = 5e-324
  • 最大值:Number.MAX_VALUE = 1.7976931348623157e+308
  • 无穷大:Infinity
  • 无穷小:-Infinity

NaN

代表非数值,是 Not a Number 的简写。

  • undefined 和任何数值计算结果都为 NaN
  • NaN 与任何值都不相等,包括 NaN 本身
  • isNaN() 可以用来判断某个变量或者表达式结果是否为非数值
// 代码示例
let test1 = 10;
let test2 = 10.23;

console.log("abc" / 18); // NaN
console.log(NaN === NaN); // false
console.log(isNaN(NaN)); // true
console.log(isNaN("blue")); // true
console.log(isNaN("123")); // false, 存在隐式转换
console.log(isNaN(123)); // false

console.log(typeof NaN === "number"); // true

4. null

null 代表的是一个空值。null 是被赋值出来的

  • null 转为数值时为0, 所以 null 与任何数值运算,可以看作 0 运算
// 代码示例
console.log(10 + null); // 10
console.log(typeof null === "object"); // 这是JS的一个bug

5. undefined

一个没有被赋值的变量的类型是 undefined,通常表示一个变量被声明了,但是没有被初始化。

  • void 0 可以用来替代 undefined
  • undefined 和任何数值计算结果都为 NaN
  • undefined 和 null 很相似,但还是有差别的

典型用法:

  1. 变量被声明了,但没有赋值时,就等于 undefined。
  2. 调用函数时,应该提供的参数没有提供,该参数等于 undefined。
  3. 对象没有赋值的属性,该属性的值为 undefined。
  4. 函数没有返回值时,默认返回 undefined。
// 代码示例
let test1; // undefiend
console.log(10 + undefined); // NaN
console.log(typeof undefined === "undefined"); // true

console.log(null == undefined); // true
console.log(null === undefined); // false,

console.log(void 0 === undefined); // true

注意: 严格比较运算符(===)和比较运算符(==)之间的差别。前者会比较操作数的类型和值,后者会将操作数的类型转换成相同的类型之后做值比较

6. symbol

ECMAScript 6 新定义

let test1 = Symbol("foo");
test1.description; // "foo"

【Javascript基础】从ECM规范看类型转换

类型转换

查看规范

to 布尔

  • 转换方法:Boolean()
  • 转换规范:转换结果为false的只有以下6种情况,其余所有情况转换结果均为 true查看原始规范说明
// undefiend
Boolean() === false
Boolean(undefined) === false
// null
Boolean(null) === false
// 0,+0,-0
Boolean(0) === false
// NaN
Boolean(NaN) === false
// ""
Boolean("") === false
// false
Boolean(false) === false

to 数值

ToNumber()是ES规范层面定义的转换方法,其内部的转换处理逻辑,参照如下转换表:
image

其中,当 Number()传入参数为字符串时,它会尝试把字符串转换为整数或者浮点数。
如果字符串中包含前导的0,不论前导0个有几个都会被忽略;如果字符串中包含一个非数字,结果都会返回NaN。这点上Number()的转换处理比parseInt()和parseFloat()要严格,具体可以看几个示例感受以下差别:

console.log(Number("0012a")); // NaN

console.log(parseInt("0012a")); // 12
console.log(parseFloat("0012.09a")); // 12.09

to 字符

跟ToNumber()一样,ToString()是ES规范层面定义的转换方法,与之对应的转换结果映射表如下:
image

to 对象

【Javascript基础】常见类型判断与转换技巧

类型比较

比较与相等

  • 等于操作符 ==

    在使用等于操作符时,会发生强制类型转换。

  • 严格的等于操作符 ===

typeof操作符

typeof null === 'object'
typeof undefined === 'undefined'

instanceof操作符

类型转换

JavaScript 深入之头疼的类型转换(上)

JavaScript 深入之头疼的类型转换(下)

  • 转字符串

    '' + 10 === '10'
  • 转数值

    +'10' === 10; // true
    
    Number('010') === 10
    parseInt('010', 10) === 10  // 用来转换为整数
    
    +'010.2' === 10.2
    Number('010.2') === 10.2
    parseInt('010.2', 10) === 10

    使用一元的加号操作符,可以把字符串转换为数字。

  • 转布尔型

    !!'foo';   // true
    !!'';      // false
    !!'0';     // true
    !!'1';     // true
    !!'-1'     // true
    !!{};      // true
    !!true;    // true

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.