javascript入门


JavaScript 是一种动态类型语言,也就是说,变量的类型没有限制,变量可以随时更改类型。

数据类型

JavaScript 语言的每一个值,都属于某一种数据类型。JavaScript 的数据类型,共有六种。(ES6 又新增了第七种 Symbol 类型的值)

  • 原始类型:数值(number):整数和小数(比如1和3.14)
  • 原始类型:字符串(string):文本(比如Hello World)。
  • 原始类型:布尔值(boolean):表示真伪的两个特殊值,即true(真)和false(假)
  • 合成类型:对象(object):各种值组成的集合
  • undefined:表示“未定义”或不存在,即由于目前没有定义,所以此处暂时没有任何值
  • null:表示空值,即此处的值为空。

只是声明变量而没有赋值,则该变量的值是undefined。undefined是一个特殊的值,表示“无定义”。


变量提升

:JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)


函数

函数是处理数据的方法,但是JavaScript 语言将函数看作一种值, 把它当成一种数据类型,可以赋值给变量,与其它值(数值、字符串、布尔值等等)地位相同。凡是可以使用值的地方,就能使用函数。由于函数与其他数据类型地位平等,所以在 JavaScript 语言中又称函数为第一等公民

JavaScript 引擎将函数名视同变量名,所以采用function命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。

function命令声明的代码区块,就是一个函数

function f1() {}
f1.name // "f1"

var f2 = function () {};
f2.name // "f2"

var f3 = function myName() {};
f3.name // 'myName'

作用域

JavaScript 只有两种作用域:一种是全局作用域,变量在整个程序中一直存在,所有地方都可以读取;另一种是函数作用域,变量只在函数内部存在。
ES6 又新增了块级作用域,

  • 全局变量(global variable) 函数外部声明的变量,它可以在函数内部读取。
  • 局部变量”(local variable) 在函数内部定义的变量,外部无法读取, 会在该作用域内覆盖同名全局变量

闭包

闭包(closure) 是 JavaScript 语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。
函数内部声明的变量,函数外是无法读取, 只有通过变通方法才能实现。那就是在函数的内部,再定义一个函数
闭包的最大用处有两个,

  1. 可以读取函数内部的变量,封装对象的私有属性和私有方法
  2. 让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。

注意,外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题。

function f1() {
  var n = 999;
  function f2() {
    console.log("函数f2就是闭包,可以读取变量n:" + n );
  }
  return f2;
}

立即调用的函数表达式(IIFE)

圆括号()是一种运算符,跟在函数名之后,表示调用该函数
但是想在定义函数之后立即调用该函数。在函数的定义之后加上圆括号会报错,原因是会出现歧义:function这个关键字即可以当作语句,也可以当作表达式
而JavaScript 引擎规定,如果function关键字出现在行首,一律解释成语句。因此,JavaScript 引擎看到行首是function关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。
解决方法就是不要让function出现在行首,让引擎将其理解成一个表达式。最简单的处理,就是将其放在一个圆括号里面

// 语句
function f() {}
// 表达式
var f = function f() {}

//错误写法
function(){ /* code */ }();// SyntaxError: Unexpected token (
//IIFE正确写法
(function(){ /* code */ }());
(function(){ /* code */ })();
//避免污染全局变量
(function () {
  var tmp = newData;
  processData(tmp);
  storeData(tmp);
}());

通常情况下,只对匿名函数使用这种“立即执行的函数表达式”。它的目的有两个:

  1. 一是不必为函数命名,避免了污染全局变量;
  2. 二是 IIFE 内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。

对象(object)

对象是 JavaScript 语言的核心概念,也是最重要的数据类型。
对象就是一组“键值对”(key-value)的集合,
对象的每一个键名又称为“属性”(property),
如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用。

var obj = {
  //obj对象的属性foo
  'foo': 'Hello',
  //obj对象的方法p
  p: function (x) {
    return 2 * x;
  }
};

对象采用大括号表示, JavaScript 引擎会产生歧义: 是对象还是代码块
为了避免这种歧义,JavaScript 引擎的做法是,如果遇到这种情况,无法确定是对象还是代码块,一律解释为代码块。
如果要解释为对象,最好在大括号前加上圆括号。因为圆括号的里面只能是表达式

{ foo: 123 } // 代码块  标签foo指向表达式123
({ foo: 123 }) // 对象  一个包含foo属性的对象

严格模式

早期的 JavaScript 语言有很多设计不合理的地方,但是为了兼容以前的代码,又不能改变老的语法,只能不断添加新的语法,引导程序员使用新语法。

严格模式是从 ES5 进入标准的,主要目的有以下几个。

  • 明确禁止一些不合理、不严谨的语法,减少 JavaScript 语言的一些怪异行为。
  • 增加更多报错的场合,消除代码运行的一些不安全之处,保证代码运行的安全。
  • 提高编译器效率,增加运行速度。
  • 为未来新版本的JavaScript 语法做好铺垫。
//老版本的引擎会把它当作一行普通字符串,加以忽略。新版本的引擎就会进入严格模式。
'use strict';
//严格模式可以用于整个脚本,也可以只用于单个函数。
  1. 显式报错
    1. 只读属性不可写
      设置字符串的length属性,会报错
    2. 只有取值器(getter)、没有存值器(setter)的属性赋值,会报错
    3. 禁止扩展的对象不可扩展
    4. eval、arguments 不可用作标识名
    5. 函数不能有重名的参数
    6. 禁止八进制的前缀0表示法
  2. 增强的安全措施
    1. 全局变量显式声明
    2. 禁止 this 关键字指向全局对象
    3. 函数内部不得使用fn.caller、fn.arguments,否则会报错。这意味着不能在函数内部得到调用栈了
    4. 函数内部使用arguments.callee、arguments.caller将会报错。
    5. 禁止删除变量
  3. 静态绑定
    某些情况下,只允许静态绑定。也就是说,属性和方法到底归属哪个对象,必须在编译阶段就确定。
    1. 禁止使用 with 语句
    2. 创设 eval 作用域
    3. arguments 不再追踪参数的变化
  4. 向下一个版本的 JavaScript 过渡
    1. 非函数代码块不得声明函数
    2. 严格模式新增了一些保留字(implements、interface、let、package、private、protected、public、static、yield等)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xyc1211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值