2015-04-09
学习JS之前可以看看JavaScript: 世界上最被误解的语言, 英文原版: JavaScript: The World's Most Misunderstood Programming Language, javascript入门: w3schools 或者 mozilla tutorials
调试输出时有如下几种方式:
JS包括两类数据类型: primitive and reference,即基本数据类型和引用类型, 引用类型就是对象(object)。基本数据类型(primitive)有如下5种:
primitive | value | typeof | comments |
---|---|---|---|
布尔型 | true, false | 'boolean' | |
数值型 | 100, 99.23 | 'number' | JS只有单一的数字类型,内部表示为64位浮点数,integer, float, double等都属于数值型 |
字符型 | "rain", 'bella' | 'string' | 单引号'与双引号"通用, 可以用 + 连接字符串, txt.length 返回长度 |
null | null | 'object' | 判断null不能使用typeof,应该使用 if (value === null) |
undefined | undefined | 'undefined' | undefined和null是不同的类型 |
除了上面5种基本数据类型,JS里其他都是object,数组/函数也是object类型,object是JS语言的核心,一切皆对象。
作为参数传递和变量赋值时,primitive是值传递
,object是引用传递
使用typeof和其他一些方法可以判断出变量数据类型:
前一节介绍了如何判断数据类型,但对于基本数据类型的包装类,String, Number, Boolean, 上面的方法无法判断,以String为例:
var str1 = 'hello world';
var str2 = new String('hello world');
console.log(typeof str1); // "string"
console.log(typeof str2); // "object", typeof无法判断出str2是一个string
应该采用下面的方法判断str2:
var str1 = 'hello world';
var str2 = new String('hello world');
console.log(Object.prototype.toString.call(str1)); //"[object String]",可以正确判断str1
console.log(Object.prototype.toString.call(str2)); //"[object String]",可以正确判断str2
string/number/boolean都有这个问题,所以,应该采用下面的方法判断string/number/boolean类型:
var isBoolean = function (obj) {
return Object.prototype.toString.call(obj) === "[object Boolean]";
};
var isString = function (obj) {
return Object.prototype.toString.call(obj) === "[object String]";
};
var isNumber = function (obj) {
return Object.prototype.toString.call(obj) === "[object Number]";
};
注意,function/array没有这个问题。
// strings
var name = "Rain Zhao"; //可以使用双引号
var gender = 'male'; //可以使用单引号
console.log(typeof name); //'string'
// numbers
var count = 25;
var cost = 1.51;
console.log(typeof count); //'number'
// boolean
var found = true;
console.log(typeof found); //'boolean'
// null
var object = null;
console.log(typeof object); //'object', 无法判断null
// undefined
var flag = undefined;
var ref; //未赋值的变量就是undefined
console.log(typeof ref); //'undefined'
//function
var foo = function(){};
console.log(typeof foo); //'function'
console.log(foo instanceof Function); //true
console.log(foo instanceof Object); //true, 函数也是对象
// array
var arr = ["rain", 3.14, {'name': 'bella'}]; //数组里可以放不同类型的元素
console.log(typeof arr); //'object', 无法判断array
console.log(Array.isArray(arr)); //true, 判断数组的最好方法
console.log(arr instanceof Array); //true,如果arr在不同frame间传递,这个方法可能不work
//因为不同frame的Array对象可能不一样,建议使用Array.isArray()
console.log(arr instanceof Object); //true, 数组也是对象
//object
var man = {
'name':'rain', //属性名可以加引号,也可以不加引号,如果属性名有空格,则需要加引号
birth: '1978', //不加引号看起来会比较直观
age: 37 //最后一个属性后不用加逗号
}
console.log(typeof man); //'object', 所有对象类型都返回'object'
console.log(man instanceof Object); //true
JS对象由3部分组成:
在NodeJS里,没有浏览器里的BOM对象和DOM对象,Node里的global对象类似window,另外node实现了file, process等native开发相关的对象。Node没有DOM对象实现, jsdom可以提供node里的DOM支持。
原生对象 | Comments | |
---|---|---|
与primitive对应的对象 | String, Number, Boolean | 不要new,应该直接使用基本数据类型 |
包装类 | Array, Object, Function | 建议不要new,应使用字面量来创建对象 |
Date, RegExp, JSON, Error | ||
内置对象 | Math | 不要new,直接使用 |
全局属性 | Infinity, NaN | -Infinity表示负无穷大 |
全局函数 | eval(), isFinite(), isNaN(), String(), Number(), parseInt(), parseFloat(), encodeURI(), decodeURI() |
更多阅读: http://www.w3schools.com/jsref/default.asp
javascript的变量声明具有hoisting机制,JavaScript引擎在执行的时候,会把所有变量的声明都提升到当前作用域的最前面, 变量看起来好像可以先使用再声明, 下面的代码是合法的:
x = 5; // Assign 5 to x
console.log(x); // 5
var x; // Declare x
变量申明会提前,但变量初始化不会提前:
var x = 5; // Initialize x
console.log("x is", x, "and y is", y); //"x is 5 and y is undefined", 可以使用变量y但y并没有初始化
var y = 7; // Initialize y
函数申明也会被提前.
注意:为了提高代码可读性,最好把所有变量都声明在当前作用域的最前面。
JavaScript既是单线程又是异步的,这种「既是单线程又是异步」的语言有一个共同特点:它们是 event-driven 的。
驱动js event 的来自一个异构的平台,即浏览器或者nodejs,browser或nodejs都是C++的,C++是多线程的,event的产生和触发,异步机制的实现都是在C++里,譬如浏览器里的DOM事件,nodejs里的各种异步事件,这些事件都是在native code里实现和管理的,js里是一组 event-handler,js引擎会保证所有 event-handler 都在同一个线程内执行,但是它们被调用的时机是由那个驱动平台决定的。
所以js engine是多线程的,但js本身是单线程的。
除了平台提供的异步事件,怎么把我们的js代码变成异步的?一个方法是使用setTimeout(),另一个办法就是使用一些现成的类库,譬如when.js, jQuery的deferred.
和Java一样JavaScript有自动垃圾回收机制,也就是说js解释器会负责管理代码执行过程中使用的内存,写代码时无需考虑内存分配及无用内存的回收问题。
早期IE使用引用计数,但可能有交叉引用问题,闭包也导致变量作用域难以管理,浏览器容易有内存泄漏问题,目前的浏览器多数采用进入环境和离开环境来记录变量,内存泄漏问题已经有很多改善。
'use strict';
var myModule = {}; myModule.name = "rain";
(function(){ your code here })()
===
代替 ==