准备以高程的章节模式,进行一下基础js的归纳与总结,大约有9章。其中有些是我自己的话,有些摘录于高程。有些则是我看了网上大佬们的总结写下来的。当然我都会标明出处。如有缺漏,欢迎指出。请多指教。


JS数据类型

ECMAScript 中有 5 种简单数据类型(也称为基本数据类型,值类型):Undefined、Null、Boolean、Number 和 String.还有 1种复杂数据类型——Object,Object 本质上是由一组无序的名值对组成的,ES6中新增复杂数据类型Symbol


1.Undefined

在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined,例如

var message
messag===undefined //true

2.Null

null值代表空对象的指针,所以在typeof判断类型时会返回"object",例如

var car=null
typeof car  //"object"
//在最基本的数据类型判断中typeof所判断出来的都是String类型

3.Boolean

bool类型只有true和false两种类型,存在对于其他类型值转换为bool值的判断

数据类型 转换为true的值 转换为false的值
Boolean true false
String 任何非空字符串 空字符串
Number 非0数字 0 NAN
Object 任何对象 null
Undefined false

4.Number

存在浮点数和整数,以及非数值(NAN),这个数值用于表示一个本来要返回数值的操作数,未返回数值的情况(这样就不会抛出错误了),针对这个值ECMAScript定义了isNaN()函数,该函数用于判断这个参数是否"不是数值"

isNaN(NAN)    // true
isNaN(10)     // fasle
isNaN("10")   // false 字符串转换成了数字
isNaN("blue") // true
isNaN(true)   // false bool类型转换成数字为1

同时有三个函数可以把非数值转换为数值 Number() ,ParseInt() ,ParseFloat()


5.String

String 类型用于表示由零或多个 16 位 Unicode 字符组成的字符序列,即字符串.存在其他类型.toString()转变为String类型,也可以String()将任何类型的值转换为字符串.


6.Object

ECMAScript 中的对象其实就是一组数据和功能的集合.对象可以通过执行 new 操作符后跟要创建的对象类型的名称来创建.


7.Symbol

为保证每个属性的名字独一无二,引入Symbol,通常可用于对象属性名的唯一确定

let s=Symbol('foo')
typeof s     // "symbol"
s            //Symbol(foo)
s.toString() // "Symbol(foo)"            

变量-作用域-内存

1.变量类型

JS中存在两种变量类型。一种是值类型、一种是引用类型。

​ 基本数据类型(值类型):undefined、null、Boolean、number、string、Symbol

​ 引用类型:Object、Array、Date、RegExg、Function

在对变量进行赋值时。如果从一个变量向另一个变量复制基本类型的值,会在变量对象上创建一个新值,然后把该值复制到为新变量分配的位置上,及两个变量虽然数值一样,但是都是存在栈空间上的完全独立存在。如果是引用类型的赋值 ,同样是将存储在变量对象的值复制一份放在新变量的分配空间。但实际上这个值的副本是一个指向原存储在堆空间对象的一个指针,在这里如果你对原对象的属性进行修改,所赋值的新对象的属性值依然会被覆盖。

ECMAScript中所有的函数参数都是按照值传递的,相当于开辟了一块的新的空间也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而引用类型值的传递,则如同引用类型变量的复制一样,如下所示。

function addTen(num) { 
 num += 10; 
 return num; 
} 

var count = 20; 
var result = addTen(count); 
alert(count); //20,没有变化
alert(result);

​ 在这个例子中,定义的count为值类型,调用函数addTen。这里传入时,先将count的值复制给参数num,在函数中num就相当于函数的局部变量,因此两个变量仅仅是数值的相同,本身是完全独立的。函数内部的变量改动不会影响函数外部的变量。同理 ,如果是传入的是引用类型。复制的是指向相同对象的地址。所以,内部改变,会影响到外部变量。这里就会牵扯到一个问题,那还是按照值类型传递么?按以下代码分析

function setName(obj) {
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
  在这个例子中创建了一个对象并将其保存在变量`person`中,然后将其复制给了参数`object`,这里两个对象引用的是同一个对象。因此 赋值了`name`之后 外部的`person`就会有了属性值。但是在函数中后面又将`obj`赋值了一个新的对象,并同样赋值了`name `属性,为什么在外部没有被修改嘞?这说明,即使在函数内部修改了参数的值,但原始的引用仍然保持未变。当在函数内部重写` obj` 时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。 **最简单的一句话讲就是引用类型的按照值传递,它这个值仅仅就是是内存地址指针,你替换的是在栈空间的一个指向对象,而不是去堆空间更改原对象**

引用https://www.jqhtml.com/45272....可进一步解释。

1.1检测类型
  1. typeof 主要用于判断基本值类型,null例外。但是在引用类型的判断时会判全部判断成object。
  2. instanceof 用于判断引用类型的值,用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性,因存在原型链的缘故。实例对象的__proto__指向了原型对象,而原型对象上的constructor属性又指回了构造函数。相当于从两边去找共同引用。如果找到,判断为true。如果是值类型则全是false
  3. constructor 是Object 类型的原型属性,它能够返回当前对象的构造器。但值得注意的是constructor可以被更改,所以是不安全的,undefined、null没有constructor方法。
  4. Object.prototype.toString.call 因为所有引用类型的类都是集成于Object,所以你可以调用父辈的prototype上的方法,如

    Object.prototype.toString()           //'[Object Object]'
    Object.prototype.toString().call(arr) //'[Object Array]'

    但是每个类都自己重写了这个方法,所以在判断的时候最后的Object会转换为自己的类型,所以调用此方法,讲call指向想要执行的对象,进行判断。但是这里如果是判断object的话,会出现上面的情况,看不出来 ,最好用instanceof

1.2 变量提升
console.log(a);
var a = 1;// 输出 undefined
===
var a 
console.log(a)
a=1
-------------------------------
console.log(foo);//输出函数foo
function foo(){
 
}

由上可知,标识符var和函数都会存在变量提升,在ES6中,新定义了let和const两个标识符,作用在于申明块级作用域。如果类似于上面的代码,把var换成let,将输出a is not defined

可参考https://segmentfault.com/a/11...


2.执行环境

执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。全局执行环境是最外围环境,在web浏览器中即windows对象。局部环境是每个函数自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。因此会形成一个作用域链。内部环境变量可依次向上寻找,找到最外层windows为止。

在ES6之前,JS没有块级作用域。如下面代码所示。

if (true) { 
 var color = "blue"; 
} 
alert(color); //"blue"

for (var i=0; i < 10; i++){ 
 doSomething(i); 
} 
alert(i); //10

第一段代码中,if声明的变量会添加到最近的环境中,即windows对象。所以外部仍能访问。第二段同理,定义的i即使是在整个for执行完后依旧是在外部的执行环境中,所以,他不能每次独立 ,而是循环的都是访问的最外环境的值。

对于标识符的查询。会沿作用域链,向上查找。如果在局部环境中找到了该标识符,搜索过程停止,变量就绪。如果在局部环境中没有找到该变量名,则继续沿作用域链向上搜索。搜索过程将一直追溯到全局环境的变量对象。如果在全局环境中也没有找到这个标识符,则意味着该变量尚未声明。

                                                                 -----总结于高程P73

3.垃圾回收

待写


yuanyuanweiwu
2 声望0 粉丝