JavaScript入坑第一步:夯实基础

拂晓

目录

  • JavaScript的基本数据类型
  • JavaScript的执行环境和作用域链
  • JavaScript的垃圾收集机制

一.JavaScript的基本数据类型

ECMAScript5中有5中基本数据类型:Undefined、Null、Boolean、Number和String。还有一种复杂数据类型——Object。

1.typeof操作符

用来检测给定变量的数据类型。

var bool = true;
console.log(typeof bool); //boolean
var number = 23;
console.log(typeof number);//number
var string = "String";
console.log(typeof string); // string
var object = Object(); 
console.log(typeof object); // object

typeof操作符不是函数,不需要使用圆括号。NULL是什么类型呢?typeof null返回值为”Object“。

2.Undefined类型

Undefined类型只是一个值,特殊的Undefined。使用var声明变量未初始化时,这个值就是Undefined。

var message;
console.log(typeof message); // undefined
console.log(type of age); // undefined

结果显示,对于未初始化和未定义的变量使用typeof操作符都会返回undefined。

3.Null类型

Null是另一个只有一个值的数据类型,就是特殊值null。从逻辑角度看,null值表示一个空对象指针。也就是前面为什么typeof null会返回Object的原因。定义一个空对象指针的时候,可以将指针设为null就可以通过相应的变量判断是否是一个对象指针。

if (car != null) {
// 对car对象执行操作
}

实际上,Undefined值是从null值派生的。因此,当我们判断 null == undefined时,返回true。

4.Boolean类型

JavaScript中经常使用的类型,该类型只有两个字面量:truefalse。注意这里区分大小写。
通过Boolean()将其他类型转换为Boolean类型。

数据类型 转为true的值 转为false的值
String 任何非空字符串 空字符串""
Number 任何非零数值 0或NaN
Object 任何对象 null
Undefined n/a undefined

5.Number类型

JavaScript中使用IEEE754格式来表示整数和浮点数值。常用的有十进制,八进制和十六进制。

var intNum = 10;
var octalNum = 070; // 56(0-7取值)
var hexNum1 = 0xA; //10 (0-F取值)

浮点数值的最高精度是17位小数,但在算数计算时精度远不如整数。
因为浮点数计算时会出现舍如误差,这是IEEE754数值计算的通病。

数值范围,在JavaScript中,最小能表示的值Number.MIN_VALUE,最大值为Number.MAX_VALUE。超出表示范围,会被自动转为Infinity(无穷)。我们可以使用isFinite()函数来检验是否在范围之间。

NaN,非数值是一个特殊的数值。表示一个本应该返回数值的操作数未返回数值的情况。NaN有两个特点,1. 任何涉及NaN的操作都返回NaN。2. NaN与任何值都不相等,包括本身。
我们可以使用isNaN()函数,检测参数是否”不是数值“。

数值转换,JavaScript中提供了三个函数:Number()parseInt()parseFloat()。第一个函数可以转换任何数据类型,后两个函数专门用于把字符串转成数值。

var num1 = Number("Hello world!"); // NaN
var num2 = Number(""); // 0
var num3 = Number("00011");//11
var num4 = Number(true);//1

使用Number()转换字符串复杂不够合理。处理字符串常用parseInt()函数,它会更多的关注是否符合数值模式。

var num1 = parseInt("1234abc"); //1234
var num2 = parseInt("");//NaN
var num3 = parseInt("0xA");//10
var num4 = parseInt("070");//56

注意: 在ECMAScript 3中num4为56,在ECMAScript 5中num4为70。

为了解决这个问题,可以给parseInt()传第二个参数:用来指定转换的进制。

var num = parseInt("0xAF", 16); // 175
//或者
var num = parseInt("AF", 16);

parseInt()类似,parseFloat()也是从第一个字符开始,直达解析到末尾或者遇到无效的浮点数字。另外,始终会忽略前导的零。

var num = parseFloat("070"); //70

6.String类型

String类型用与表示零或多个16位Unicode字符组成的字符序列。在JavaScript中,使用双引号和单引号表示,两者没有任何区别。

字符串是不可变的,一旦创建就不可以修改。

数值转为字符串有两种方式:toString()String()。第一个方法,返回数值的字符串表示形式。第二个可以将任何类型的值转为字符串,在不知道转值是否为null和undefined时使用。

7.Object类型

ECMAScript中对象其实就是一组数据和功能的集合。

var object = new Object();

创建一个对象,与Java很相似。Object类型是所有他的实例的基础。也就是,Object类型所具有的任何属性和方法同样存在于更具体的对象中。

Object的每个实例具有的属性和方法:

  • constructor : 构造函数。用于创建对象的函数。
  • hasOwnProperty(propertyName): 用于检查给定的属性在当前对象实例中是否存在。参数以字符串形式表示o.hasOwnProperty("name")
  • isPrototypeof(object):用于检查传入的对象是否是当前对象的原型。
  • propertyIsEnumerable(propertyName): 用于检查给定的属性是否能够使用for-in语句。
  • toLocaleString():返回对象的字符串表示。
  • toString(): 返回对象的字符串表示。
  • valueOf(): 返回对象的字符串、数值或布尔值表示。

Object是所有对象的基础,因此所有对象都具有这些基本的属性和方法。

二.JavaScript的作用域

JavaScript的变量和其他语言有很大差别。JavaScript的变量是松散类型的本质,所谓的松散类型就是可以保存任何类型的数据。这个本质决定了它只是保存特定值的名字而已。因为这个属性,变量的值和数据类型可以在脚本的生命周期内改变。

1.基本类型和引用类型

ECMAScript中包含两种不同的数据类型值: 基本类型值和引用类型值。基本类型值是指简单的数据段,引用类型值值那些可能由多个值构成的对象。

动态的属性,只能给引用类型值动态添加属性。

复制,基本类型复制值,引用类型复制指针。

传递参数,所有函数的参数都是按值传递的。基本类型值很好理解,直接传递值。但是,引用类型值也是按值传递的。

function setName(objc) {
    objc.name = "Owenli";
}
var person = new Object();
setName(person);
console.log(person.name); //Owenli

创建了一个person对象,传递给setName()函数之后被复制给objc。在函数内部,objc和person引用的是同一个对象。即使是按值传递的,objc也会按引用来访问同一个对象。添加name属性后,person也会有反应,因为person指向的对象在堆中只有一个,并且是全局对象。

这是有人会误以为是引用传递,那么看下一个示例:

function setName(objc) {
    objc.name = "Owenli";
    objc = new Object();
    objc.name = "Tom";
}
var person = new Object();
setName(person);
console.log(person.name);

这段代码输出什么呢? 如果你认为输出 Tom,那就入坑了。其实结果是Owenli。即使在函数内部修改了参数的值,但原始的引用仍然保持不变。实际上,虽然在setName()函数中,将新对象赋给objc,这个变量引用的是局部对象,在函数执行完毕后立即被销毁。

参数传递

检测类型,之前typeof操作符用来检测基本类型,但是用来检测引用类型需要使用instanceof操作符。

2.执行环境和作用域

执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为,每个执行环境都有一个与之关联的变量对象(varable object),函数中定义的多有变量和函数都保存到这个对象中。

每个函数都有自己的执行环境,当执行流进入一个函数,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返给之前的执行环境。

当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象最开始只包含一个变量,即arguments对象。

举个

var color = "blue";
function changeColor() {
    var anotherColor = "red";

    function swapColors() {
        var tempColor  anotherColor;
        anotherColor = color;
        color = tempColor;
        //访问color,anotherColor和tempColor
    }
    // 访问color和anotherColor,但不能访问tempColor
    swapColors();
}
// 只能访问color
changeColor();

作用域链效果图:

作用域链.jpg

内部环境可以通过作用域链访问所有的外部环境,但是外部环境不可以访问内部环境中的任何变量和函数。环境之间的联系是线性、有序的。每个环境都可以向上搜索作用域链,以查询变量和函数名。

延长作用域链,环境类型只有两种:全局和局部(函数),但还有其他方法来延长作用域链。

  • try-catch语句的catch块
  • with语句

这两个语句都会在作用域链的前端添加一个变量对象。with语句,就会指定的对象添加到作用域链中。catch语句,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。

没有块级作用域,和其他语言相比,JavaScript没有块级作用域。例如,

 if (true) {
    var color = "blue";
  }
  console.log(color);

在C语言中,会在if语句结束后销毁color。但是在JavaScript中,if中声明的变量会被添加到当前的执行环境中(上面是全局环境)。

for (var i = 0; i < 10; i ++) {
    ///dosomething
}
console.log(i); // 10

注意:JavaScript中,即使for循环结束,i仍然存在于当前的执行环境中。

变量声明,使用var声明的变量会被添加到最近的环境中。如果声明没有使用var则会被添加到全局环境中。

标识符搜索,搜索过程是从作用域链的前端开始,向上逐级查询与给定名字匹配的标识符。如果局部环境中存在着同名标识符,那么就不会使用位于父级的标志符。

标识符查找.jpg

三.垃圾收集

JavaScript具有自动垃圾收集机制,执行环境负责管理代码执行过程中使用的内存。垃圾回收原理:垃圾收集器会周期地找到那些不在使用的变量,然后释放其内存。两种垃圾回收策略:标记清除和引用计数。

1.标记清除

JavaScript中最常用的垃圾收集方法标记清除。当变量进入环境标记为“进入环境”,此状态下变量可能会用到。当变量离开环境时,将其标记为“离开环境”,此时可以被垃圾收集器回收。

2.引用计数

在Objective-C中使用引用计数。关于引用计数可以看《iOS高级编程》第一章。注意引用计数存在循环引用问题。

性能问题,由于垃圾收集器是周期运行的,所以确定时间间隔是一个非常重要的问题。IE曾因为这个出现过性能问题。

管理内存,出于安全角度考虑,给Web浏览器分配的内存数量通常比分配给桌面应用的少。因此,一旦数据不再用,最好通过将其值设置为null来释放其引用——接触引用。解除一个引用不代表立即被回收,只是让其脱离执行环境,以便垃圾收集器下次运行时将其回收。

小结

  • 首先,学习javaScript的基本数据类型,有其他编程语言基础,学起来很简单,只需记住不同点即可。
  • 其次,学习javaScript的作用域链和执行环境,理解作用域链和执行环境等概念对后期的学习很有帮助,需要充分理解。
  • 最后,javaScript的垃圾收集机制,最常用的是标记清除。iOS中使用的是引用计数。
  • 下一篇学习JavaScript中对象。

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容

  • 第1章 JavaScript 简介 JavaScript 具备与浏览器窗口及其内容等几乎所有方面交互的能力。 欧洲...
    力气强阅读 1,118评论 0 0
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,219评论 0 4
  • 最近火爆朋友圈的分答你玩了嘛? 据说是你睡了,你的问题还在替你赚钱的付费问答产品。 我特意去百度搜了下,得出的结论...
    五点人家阅读 155评论 3 3
  • 太极生两仪, 两仪生四象, 四象生八卦, 八卦定吉凶。
    MissSad阅读 95评论 0 0