局部作用域

由于JavaScript的变量作用域实际上是函数内部,我们在for循环等语句块中是无法定义具有局部作用域的变量的:

'use strict';

function foo() {
for (var i=0; i<100; i++) {
//
}
i += 100; // 仍然可以引用变量i
}

为了解决块级作用域,ES6引入了新的关键字let,用let替代var可以申明一个块级作用域的变量:

'use strict';

function foo() {
var sum = 0;
for (let i=0; i<100; i++) {
sum += i;
}
i += 1; // SyntaxError
}

类型的变量

访问属性是通过.操作符完成的,但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用''括起来:

var xiaohong = {
name: '小红',
'middle-school': 'No.1 Middle School'
};

xiaohong的属性名middle-school不是一个有效的变量,就需要用''括起来。访问这个属性也无法使用.操作符,必须用['xxx']来访问:

xiaohong['middle-school']; // 'No.1 Middle School'
xiaohong['name']; // '小红'
xiaohong.name; // '小红'

也可以用xiaohong['name']来访问xiaohong的name属性,不过xiaohong.name的写法更简洁。

我们在编写JavaScript代码的时候,属性名尽量使用标准的变量名,这样就可以直接通过object.prop的形式访问一个属性了。

由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性:

var xiaoming = {
name: '小明'
}; xiaoming.age; // undefined
xiaoming.age = 18; // 新增一个age属性
xiaoming.age; // 18 delete xiaoming.age; // 删除age属性 xiaoming.age; // undefined
delete xiaoming['name']; // 删除name属性 xiaoming.name; // undefined
delete xiaoming.school; // 删除一个不存在的school属性也不会报错

如果我们要检测xiaoming是否拥有某一属性,可以用in操作符:

var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
}; 'name' in xiaoming; // true
'grade' in xiaoming; // false

Note:如果in判断一个属性存在,这个属性不一定是xiaoming的,它可能是xiaoming继承得到的:

'toString' in xiaoming; // true

因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以xiaoming也拥有toString属性。

要判断一个属性是否是xiaoming自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法:

var xiaoming = {
name: '小明'
}; xiaoming.hasOwnProperty('name'); // true
xiaoming.hasOwnProperty('toString'); // false

javaScript把null、undefined、0、NaN和空字符串''视为false,其他值一概视为true,因此上述代码条件判断的结果是true。

for ... in

for循环的一个变体是for ... in循环,它可以把一个对象的所有属性依次循环出来:

var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
}; for (var key in o) {
alert(key); // 'name', 'age', 'city'
}

要过滤掉对象继承的属性,用hasOwnProperty()来实现:

var o = {
name: 'Jack',
age: 20,
city: 'Beijing'
};
for (var key in o) {
if (o.hasOwnProperty(key)) {
alert(key); // 'name', 'age', 'city'
}
}

由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引:

var a = ['A', 'B', 'C'];
for (var i in a) {
alert(i); // '0', '1', '2'
alert(a[i]); // 'A', 'B', 'C'
}

请注意,for ... in对Array的循环得到的是String而不是Number。

名字空间

全局变量会绑定到window上,不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,都会造成命名冲突,并且很难被发现。

减少冲突的一个方法是把自己的所有变量和函数全部绑定到一个全局变量中。例如:

// 唯一的全局变量MYAPP:
var MYAPP = {}; // 其他变量:
MYAPP.name = 'myapp';
MYAPP.version = 1.0; // 其他函数:
MYAPP.foo = function () {
return 'foo';
};

把自己的代码全部放入唯一的名字空间MYAPP中,会大大减少全局变量冲突的可能。

许多著名的JavaScript库都是这么干的:jQuery,YUI,underscore等等。

常量

由于var和let申明的是变量,如果要申明一个常量,在ES6之前是不行的,我们通常用全部大写的变量来表示“这是一个常量,不要修改它的值”:

var PI = 3.14;

ES6标准引入了新的关键字const来定义常量,const与let都具有块级作用域:

'use strict';

const PI = 3.14;
PI = 3; // 某些浏览器不报错,但是无效果!
PI; // 3.14

js variable 变量的更多相关文章

  1. 深入理解js的变量提升和函数提升

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...

  2. js之变量和作用域

    JS的变量和其他语言的变量有很大区别.JS变量时“松散型”的,决定它只是在特定时间用于保存特定的一个名字而已.由于不存在变量要保存何种数据类型,变量的值和其数据类型可以在脚本的生命周期内改变. JS两 ...

  3. Js字面变量,定义问题

    Js字面变量.浏览器的版本问题:

  4. js学习--变量作用域和作用域链

    作为一名菜鸟的我,每天学点的感觉还是不错的.今天学习闭包的过程中看到作用域与作用域链这两个概念,我觉得作为一名有追求的小白,有必要详细了解下. 变量的作用域 就js变量而言,有全局变量和局部变量.这里 ...

  5. js中变量提升(一个是变量,一个是函数表达式都会存在变量提升,函数声明不存在)

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...

  6. 使用 v-cloak 防止页面加载时出现 vue.js 的变量名

    知识点:使用 v-cloak 防止页面加载时出现 vue.js 的变量名 场景:在使用vue语法,实现下拉框功能时,展示数据列表之前,出现对应的 vuejs 变量名 代码: var vm = new ...

  7. js 的概念和声明-js 的变量-js 的运算符和逻辑结构-js 的数组

    js 的概念和声明Js的概念和声明:问题:在网页的发展历程中,发现网页不能对用户的数据进行自动校验,和提供一些特效造成用户体验极差解决:使用JavaScript作用:可以让网页和用户之间进行直接简单的 ...

  8. win 环境下 node.js环境变量

     在win 环境下 node.js环境变量有两种情况:  (1)开发环境(development):开发环境是程序猿们专门用于开发的服务器,配置可以比较随意, 为了开发调试方便,一般打开全部错误报告. ...

  9. 深入理解js的变量提升和函数提升(转)

    一.变量提升 在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域.变量提升即将变量声明提升到它所在作用域的最开始的部分.上个简历的例子如: ...

随机推荐

  1. Tornado 框架的使用

    Tornado tornado是一个轻量级python的web框架,他是非阻塞式的,而且速度非常快.得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,这意味着 ...

  2. javascript面向对象的程序设计之Object.getOwnPropertyDescriptor()

    Object.getOwnPropertyDescriptor()用于获取给定属性的描述信息,这个描述信息是一个对象. 如果是访问器属性,则这个对象的属性有configurable,enumerabl ...

  3. 记录——node-mysql连接池遇到的全局变量问题

    记录一个折腾了快2个小时的BUG,目前还不清楚原理. 系统分别在阿里云(测试用).XL服务器上部署,此次BUG所在功能模块为生成表格并下载,表格数据由120(阿里云)上的数据库提供. 阿里云上一切正常 ...

  4. Oauth2.0(六):Resource Owner Password Credentials 授权和 Client Credentials 授权

    这两种简称 Password 方式和 Client 方式吧,都只适用于应用是受信任的场景.一个典型的例子是同一个企业内部的不同产品要使用本企业的 Oauth2.0 体系.在有些情况下,产品希望能够定制 ...

  5. Python小代码

    from bs4 import BeautifulSoup import requests url = 'http://www.tripadvisor.cn/Attractions-g60763-Ac ...

  6. CentOS Apache配置详解

    要想在linux上实现网页服务器(www)需要Apache这个服务器软件,不过Apache仅能提供最基本的静态网站数据而已,想要实现动态网站的话,最好还是要PHP与MySQL的支持,所以下面我们将会以 ...

  7. Node MonGoDb 简单的增删改查

    let MongoClient = require("mongodb").MongoClient; let url = "mongodb://192.168.200.10 ...

  8. XE 创建 Active Form

    XE6: http://docwiki.embarcadero.com/RADStudio/XE6/en/Generating_an_Active_Form_Based_on_a_VCL_Form h ...

  9. ABAP-语音输出

    REPORT ZRICO_SPEAK. include ole2incl. data:ole type ole2_object, voice type ole2_object. parameters: ...

  10. 不定宽高的DIV,垂直水平居中

    1.怎么让一个不定宽高的DIV,垂直水平居中? 答:1)使用CSS方法. 父盒子设置: display:table-cell; text-align:center; vertical-align:mi ...