Reference Types(引用类型)

主要内容:

  • 使用对象(objects)
  • 创建并操作数组
  • 理解JavaScript的基本数据类型
  • 使用 primitives 和 primitive wrappers

上一篇提到的引用变量就是引用类型的一种实例。在JavaScript中,引用类型是把data和functionality组合在一起的一种结构,通常被误称为classes。尽管严格来说JavaScript被称为面向对象语言,但是它缺少了传统面向对象语言中接口和类这些基本组件。因为它们也描绘了objects拥有的propertys和methods,所以引用类型有时也会被称为objects definitions(reference types不等于classes。)

再次强调,objects是reference types的一种特殊实例。JavaScript提供了一系列原生引用类型。

//通过new操作符和构造函数Object()创建一个Object引用类型。
//构造函数创建了一个拥有基本property和methods的简单对象。
var person = new Object();

Object 类型

两种声明方式:

//第一种
var person = new Object();
person.name = "Jack";
person.age = 5;
//第二种,特点简单易懂,number类属性会自动转换为string类属性,
//比如5会转化为"5"
var person2 = {
    name : "Peter",
    age : 12,
    5 :true
}

第二种,字面量方式(literal notions),同样也可用于传递可选参数,如果用传统方式传递多个参数就会显得臃肿:

function displayInfo(args) {
    var output = "";
    if (typeof args.name == "string"){
        output += "Name: " + args.name + “\n”;
    }
    if (typeof args.age == "number") {
        output += "Age: " + args.age + "\n";
    }
    alert(output);
}
displayInfo({
    name: "Nicholas",
    age: 29
});
displayInfo({
    name: "Greg"
});

获取属性值两种方式:

console.log(person2.name);//12
console.log(person2["name"]);//12
//第二种的好处在于还可以像下面这样用
var p = "age"; 
console.log(person2[p]);//12
//甚至
console.log(person2["test 01"]);//键值字符串可以放空格

Array 类型

  1. JavaScript中的数组可以储存不同的变量
  2. JavaScript中数组的大小是动态变化的,可以随着添加的元素增长

创建方式:

var Color = new Array();
var Color2 = new Array(10);//指定长度为10的数组
var Color3 = new Array("red","blue","yellow");//直接用值初始化

注意: 参数类型为Number时与其它类型不同

var name = new Array("Nick");//数组中包含一个字符串"Nick"
var Color = new Array(10);//指定长度为10的数组
//省略new也可以
var name2 = Array("Nick");
var Color2 = Array(10);

另一种,字面量创建方式

var colors = ["red","blue","yellow"];
var c2 = [];
var c3 = [1,2,];//会创建length为2或3的数组,这点需要注意
var options = [,,,,,];//会创建length为5或6的数组,不建议这样使用
var colors = ["red","blue","yellow"];
console.log(colors[0]);//读
colors[2]="green";//改
console.log(colors.length);//3
colors[3]="black";//增,数组大小也会动态增加
console.log(colors.length);//4
//可以通过设置length 属性(property)来控制数组大小
colors.length=2;
console.log(colors[2]);//undefined
colors[99]=1;
console.log(colors.length);//100

检测是否为数组

if(Array.isArray(value)){//推荐
    //do sth.
}

转化方法

//creates an array with three strings
var colors = ["red", "blue", "green"];
alert(colors.toString()); //red,blue,green
alert(colors.valueOf()); //red,blue,green

//隐式调用toString()
alert(colors); //red,blue,green

toLocaleString方法和另外两个方法的唯一区别就是:

var person1 = {
    toLocaleString : function () {
        return "Nikolaos";
    },
    toString : function() {
        return "Nicholas";
    }
};
var person2 = {
    toLocaleString : function () {
        return "Grigorios";
    },
    toString : function() {
        return "Greg";
    }
};
var people = [person1, person2];
alert(people); //Nicholas,Greg
alert(people.toString()); //Nicholas,Greg
alert(people.toLocaleString()); //Nikolaos,Grigorios

分割符可以手动设置:

var a;
var colors = ["red", "green", "blue"];
alert(colors.join(",")); //red,green,blue
alert(colors.join("||")); //red||green||blue
alert(colors.join()); //red,green,blue
alert(colors.join(a)); //red,green,blue
colors.length=5;
//未定义的变量用空字符串填充,toString、toLocaleString、valueOf同样。
alert(colors.join(",")); //red,green,blue,,

栈方法

JavaScript提供了个方法,使得它的数组表现的和其它语言的一样。push()和pop()方法提供了类似的功能。

var colors = new Array();
var count = colors.push("red","green");
alert(count);//2
count = colors.push("black");
alert(count);//3
var item = colors.pop();
alert(item);//black
alert(colors.length);//2
//当然可以和其它方法混用
colors[2]="yellow";
alert(colors.pop());//yellow

队列(queue)方法

数组是“先进后出”原则,队列是“先进先出”原则。

var colors = new Array();
var count = colors.push("red","green");
alert(count);//2
count = colors.push("black");
alert(count);//3
var item = colors.shift();//用shift模拟先进先出
alert(item);//red

移走数组第一个变量后,所有变量向前移动一个单位。

var colors = new Array();
var count = colors.unshift("red","green");//与shift方法作用相反
alert(count);//2
count = colors.unshift("black");
alert(count);//3
var item = colors.pop();//
alert(item);//black

重新排序

var values = [1,2,3,4,5];
values.reverse();//5,4,3,2,1
alert(values);
var values2 = [1,10,5,15,2];
values2.sort()
alert(values2);//1,10,15,2,5 按字符串先后顺序排列
//sort可以传函数为参
function compare(num1,num2){
    if(num1<num2){
        return 1;
    }else if(num1>num2){
        return -1;
    }
    else{
        return 0;
    }
}
values2.sort(compare);
alert(values2);//15,10,5,2,1
//compare简化版为:
function compare(num1,num2){
    return num1-num2;
}

如果只是想倒序,reverse速度要比sort快。

操作方法

var values = [1,2,3,4,5];
var values_new = values.concat(7,[8,9]);
alert(values);//1,2,3,4,5
alert(values_new);//1,2,3,4,5,7,8,9

var colors = ["red", "green", "blue", "yellow", "purple"];
var colors2 = colors.slice(1);//起始位置:1,结束位置:最后
var colors3 = colors.slice(1,4);//起始位置:1,结束位置:4,不包括位置4
var colors4 = colors.slice(-2,-1);
var colors5 = colors.slice(-1,-2);//起始大于结束返回空字符串
alert(colors2); //green,blue,yellow,purple
alert(colors3); //green,blue,yellow
alert(colors4); //yellow
alert(colors5); //空字符串

最有用数组方法:splice()

//删除,两个参数,起始位置和要删除的个数
var colors = ["red","blue","yellow"];
var removed = colors.splice(0,1);
alert(removed);//red
alert(colors);//blue,yellow
//插入,参数,插入位置,删除的元素,添加的元素
removed = colors.splice(1,0,"yellow","orange");
alert(colors);//blue,yellow,orange,yellow
alert(removed);//空字符串
//替换,用法参照上面
removed = colors.splice(1,1,"red","purple");
alert(colors);//blue,red,purple,orange,yellow
alert(removed);//yellow

定位(Location)方法

直接上代码:

var numbers = [1,2,3,4,5,4,3,2,1];
alert(numbers.indexOf(4)); //3
alert(numbers.lastIndexOf(4)); //5
alert(numbers.indexOf(4, 4)); //5 第二个参数为起始搜索位置索引
alert(numbers.lastIndexOf(4, 4)); //3
var person = { name: "Nicholas" };
var people = [{ name: "Nicholas" }];
var morePeople = [person];
//indexof获取组项(items)必须保证严格满足搜寻条件,就如“===”
//people[0]为对象,morePeople[0]为对象引用
alert(people.indexOf(person));      // -1
alert(morePeople.indexOf(person));  //0

迭代方法(Iterative Methods)

支持浏览器:Internet Explorer 9+, Firefox 2+, Safari 3+,
Opera 9.5+, 和 Chrome.

  1. JavaScript一共有五个针对数组(arrays)的方法,接受一个function参数(run on each item)和一个可选参数(a scope object in which to run the function (affecting the value of this))。
  2. 传入的函数接受三个参数,第一个参数为数组项(item),第二个为数组项位置,第三个为数组(array object itself)。
  3. 这些方法都不会改变原数组。
var numbers = [1,2,3,4,5,4,3,2,1];
//所有都满足条件
var everyResult = numbers.every(function(item, index, array){
    return (item > 2);
});
alert(everyResult); //false
//至少有一个满足条件
var someResult = numbers.some(function(item, index, array){
    return (item > 2);
});
alert(someResult); //true
//顾名思义,筛选
var numbers = [1,2,3,4,5,4,3,2,1];
var filterResult = numbers.filter(function(item, index, array){
return (item > 2);
});
alert(filterResult); //[3,4,5,4,3]
//显而易见
var numbers = [1,2,3,4,5,4,3,2,1];
var mapResult = numbers.map(function(item, index, array){
return item * 2;
});
alert(mapResult); //[2,4,6,8,10,8,6,4,2]

Reduction Methods

支持浏览器:Internet Explorer 9+, Firefox 3+, Safari 4+, Opera 10.5,
和 Chrome

两个方法 reduce()和 reduceRight()
1. 接受一个function参数(run on each item)和一个可选参数(optional initial value upon which the reduction is based)。
2. 传入的函数接受三个参数,第一个参数为前一个数组项值(previous value),第二个为当前数组项值(current value),第三个为为数组项位置,第四个为数组(array object itself)。
3. 函数从数组第二个元素开始执行,所以第一个数组项作为第一个参数第一次传入函数,每一次返回的结果又作为第二次迭代的第一个参数传入。

var values = [1,2,3,4,5];
var sum = values.reduce(function(prev, cur, index, array){
    return prev + cur;
});
alert(sum); //15
//反方向执行
var values = [1,2,3,4,5];
var sum = values.reduceRight(function(prev, cur, index, array){
return prev + cur;
});
alert(sum); //15

日期类型

理论上来说,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。由于地球在它的椭圆轨道里的运动速度不均匀,这个时刻可能和实际的太阳时相差16分钟。地球每天的自转是有些不规则的,而且正在缓慢减速。地球每天的自转是有些不规则的,而且正在缓慢减速。所以,格林尼治时间已经不再被作为标准时间使用。现在的标准时间——协调世界时(UTC)——由原子钟提供。

辅助函数两个:Date.parse() 和 Date.UTC()
Date.parse()
参数:
1. “6/13/2004”
2. “January 12, 2004”
3. “Tue May 25 2004 00:00:00 GMT-0700)”
4. “2004-05-25T00:00:00”

//now为当前时间
var now = new Date();
console.log(now);
var someDate = new Date(Date.parse("May 25, 2004"));
console.log(someDate);
someDate = new Date("May 25, 2004");//结果同上
console.log(someDate);

Date.UTC()
参数:
1. 年
2. 月(0-11)
3. 日 (1-31)
4. 时 (0-23)
5. 分
6. 秒
7. 毫秒

//格林威治时间(GMT) 2000年1月
var y2k = new Date(Date.UTC(2000, 0));
//格林威治时间(GMT) 2005年5月5日下午 5:55:55 
var allFives = new Date(Date.UTC(2005, 4, 5, 17, 55, 55));

//和上面的区别,格林威治时间和本地时间的区别
//本地时间 2000年1月
var y2k = new Date(2000, 0);
//本地时间 2005年5月5日下午 5:55:55 
var allFives = new Date(2005, 4, 5, 17, 55, 55);

ES5引入Date.now(),

浏览器支持Internet Explorer 9+, Firefox 3+, Safari 3+,
Opera 10.5, 和Chrome.

//计算doSomething耗时
//get start time
var start = Date.now();
//call a function
doSomething();
//get stop time
var stop = Date.now(),
result = stop – start;
//如果浏览器不支持可以用下面的方式
//get start time
var start = +new Date();
//call a function
doSomething();
//get stop time
var stop = +new Date(),
result = stop – start;

继承方法

toLocaleString和toString在各个浏览器的表现:
Internet Explorer 8
toLocaleString() — Thursday, February 01, 2007 12:00:00 AM
toString() — Thu Feb 1 00:00:00 PST 2007
Firefox 3.5
toLocaleString() — Thursday, February 01, 2007 12:00:00 AM
toString() — Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)
Safari 4
toLocaleString() — Thursday, February 01, 2007 00:00:00
toString() — Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)
Chrome 4
toLocaleString() — Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)
toString() — Thu Feb 01 2007 00:00:00 GMT-0800 (Pacific Standard Time)
Opera 10
toLocaleString() — 2/1/2007 12:00:00 AM
toString() — Thu, 01 Feb 2007 00:00:00 GMT-0800

由于在各个浏览器表现不同,一般这些结果只能用来调试,而不适合展示。

valueof() 函数返回时间戳(时间戳就是从1970年1月1日0时0分0秒到当前时间点的所有秒数),用于例如比较操作符:

var date1 = new Date(2007, 0, 1); //”January 1, 2007”
var date2 = new Date(2007, 1, 1); //”February 1, 2007”
alert(date1 < date2); //true
alert(date1 > date2); //false
alert(date1.valueOf()); //时间戳

时间格式化方法

toDateString()、toTimeString()toLocaleDateString()、toLocaleTimeString()、toUTCString()同toLocaleString() 和 toString()一样,不同的浏览器表现不同,不建议在用户界面显示一致的信息。

Date/Time组件方法

方法

描述

getTime()

显示时间的毫秒数

setTime(milliseconds)

用毫秒数设置时间,会改变整个时间

getFullYear()

获取四位数年数

。。。

。。。

正则表达式类型

使用方式:
var expression = /pattern/flags;

  • g – 全局匹配模式,找到所有满足条件的字符串而非找到第一个就停止。
  • i – 忽略大小写模式,匹配模式时会略大小写。
  • m – 多行模式,查询到当前text最后一行时继续查找。
    例子:
// 找到所有包含"at"的字符串
var pattern1 = /at/g;
// 找到第一个(注意和上面的区别)包含"bc"和"at"的字符串,忽略大小写
var pattern2 = /[bc]at/i;
// 找到三个字符结尾为"at"的字符串,忽略大小写
var pattern3 = /.at/gi;

正则元字符:
( [ { \ ^ $ | ) ] } ? * + .
如果想用这些字符的原意,需要转义字符”\”

//找到所有包含"[bc]at"的字符串
var pattern2 = /\[bc\]at/g;

使用正则表达式字面量和使用 RegExp 构造函数创建的正则表达式不一样。在 ECMAScript 3 中, 正则表达式字面量始终会共享同一个RegExp实例,而使用构造函数创建的每一个新RegExp实例都是一个新实例。来看下面的例子。

var re = null,
        i;
for (i=0; i < 10; i++){
    re = /cat/g;
    re.test("catastrophe");
}
for (i=0; i < 10; i++){
    re = new RegExp("cat", "g");
    re.test("catastrophe");
}

在第一个循环中,即使是循环体中指定的,但实际上只为 /cat/ 创建了一个 RegExp 实例。由于实例属性不会重置,所以在循环中再次调用 test() 方法会失败。这是因为第一次调用 test() 找到了”cat”,但第二次调用是从索引为 3 的字符(上一次匹配的末尾)开始的,所以就找不到它了。由于会测试到字符串末尾,所以下一次再调用 test()就又从开头开始了。

第二个循环使用 RegExp 构造函数在每次循环中创建正则表达式。因为每次迭代都会创建一个新的 RegExp 实例,所以每次调用 test()都会返回 true。

ES5 规定字面表达式表现要与直接调用RegExp 构造函数一样。 Internet Explorer 9+, Firefox 4+, 和 Chrome已经跟进了。

正则实例属性

正则实例方法

  • 基本方法:exec()
  • 用于获取组:capturing groups
  • 参数:执行模式的string
  • 返回:第一个满足条件的array of information 或者 null
    尽管返回的是 Array 实例,包括两个额外属性
    index:满足模式的string位置
    input:执行操作的string
    在数组中,第一项是满足整个模式的string,第二,三个如下
var text = "mom and dad and baby";
var pattern = /mom( and dad( and baby)?)?/gi;

var matches = pattern.exec(text);
alert(matches.index); //0
alert(matches.input); //”mom and dad and baby”
alert(matches[0]); //”mom and dad and baby”
alert(matches[1]); //” and dad and baby”
alert(matches[2]); //” and baby”
var text = "cat, bat, sat, fat";
var pattern1 = /.at/;
//如果未指定flag含"g",执行多次exec()也只会返回第一个满足条件的信息。
var matches = pattern1.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern1.lastIndex); //0

matches = pattern1.exec(text);
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern1.lastIndex); //0

//flag含"g",lastIndex也会受影响,指定下一个满足条件的index
var pattern2 = /.at/g;

var matches = pattern2.exec(text); 
alert(matches.index); //0
alert(matches[0]); //cat
alert(pattern2.lastIndex); //3

matches = pattern2.exec(text);
alert(matches.index); //5
alert(matches[0]); //bat
alert(pattern2.lastIndex); //8

在IE中,lastIndex即使在非全局模式下,也会改变。

  • 另一个方法,test()
var text = "000-00-0000";
var pattern = /\d{3}-\d{2}-\d{4}/;

if (pattern.test(text)){
 alert("The pattern was matched.");
}
  • 继承方法:
//两个返回的如字面表达式定义的那样。
var pattern = new RegExp("\\[bc\\]at", "gi");
alert(pattern.toString()); // /\[bc\]at/gi
alert(pattern.toLocaleString()); // /\[bc\]at/gi
//

正则构造函数属性

JavaScript正则表达式不支持的功能

函数对象

  • 在JavaScript中,函数也是对象。
  • 因为函数是对象,所以函数名是指向函数对象的指针而并不必要绑定函数本身。
  • 三种构造方式
//1
function sum (num1, num2) {
    return num1 + num2;
}
//2
var sum = function(num1, num2){
    return num1 + num2;
};
//3 不推荐
var sum = new Function("num1", "num2", "return num1 + num2"); //not recommended

因为函数是对象,由于对象是按共享传递的,所以如下:

function sum(num1, num2){
    return num1 + num2;
}
alert(sum(10,10)); //20
var anotherSum = sum;
alert(anotherSum(10,10)); //20
sum = null;//共享传递,所以sum为0不影响。
alert(anotherSum(10,10)); //20

不能重载

function addSomeNumber(num){
return num + 100;
}
function addSomeNumber(num) {
return num + 200;
}
var result = addSomeNumber(100); //300

函数声明和函数表达式的对比

函数声明提升(function declaration hoisting)

//函数声明,这种情况会有函数提升,
alert(sum(10,10));
function sum(num1, num2){
    return num1 + num2;
}
//函数表达式,这种情况报错
alert(sum(10,10));
var sum = function(num1, num2){
    return num1 + num2;
};

像操作值那样操作函数

function createComparisonFunction(propertyName) {
    return function(object1, object2){
    var value1 = object1[propertyName];
    var value2 = object2[propertyName];
    if (value1 < value2){
        return -1;
    } else if (value1 > value2){
        return 1;
    } else {
        return 0;
    }
    };
}

函数内部

在函数内部有两个重要的对象:arguments 和 this
arguments:存放所有参数的数组,属性 callee 指向拥有它的function对象。

function factorial(num){
    if (num <= 1) {
        return 1;
    } else {
        return num * factorial(num-1)
    }
}
//等同于
function factorial(num){
    if (num <= 1) {
        return 1;
    } else {
        return num * arguments.callee(num-1)
    }
}

//因为函数名是指针,所以虽然全局的sayColor()和o.sayColor()在不同的上下文(context)里,但是它们都指向同一个函数。

window.color = "red";
var o = { color: "blue" };
function sayColor(){
    alert(this.color);
}
sayColor(); //"red",this指向window
o.sayColor = sayColor;
o.sayColor(); //"blue",this指向o

ES5又给函数添加了另外一个属性:caller

支持浏览器:Internet Explorer, Firefox, Chrome, 和 Safari, Opera 9.6

function outer(){
    inner();
}
function inner(){
    alert(inner.caller);
}
outer();
//同下
function outer(){
    inner();
}
function inner(){
    alert(arguments.callee.caller);
}
outer();

打印结果:inner调用者的表达式
function outer(){
inner();
}


在strict mode执行时,尝试访问 arguments.callee 会报错,ES5同样定义了在strict mode下 arguments.caller 会报错,非strict mode下为undefined,这样就避免了arguments.caller 和函数的caller让人混淆,这是为了加强语言的安全性,防止第三方代码窥探上下文代码(毕竟返回的是执行函数)。strict mode也做了限制,你不能给函数的caller 属性赋值。

函数的属性和方法

两个属性:length 和 prototype
length 获取的是有名参数个数

function sayName(name){
    alert(name);
}
function sum(num1, num2){
    return num1 + num2;
}
function sayHi(){
    alert("hi");
}
alert(sayName.length); //1
alert(sum.length); //2
alert(sayHi.length); //0

prototype 中文意思 原型,是引用类型所有方法实际存在位置,在ES5中,prototype属性不能枚举,使用for-in也不能找到。

还有两个方法,apply() 和 call()。一看就懂。

function sum(num1, num2){
    return num1 + num2;
}
function callSum1(num1, num2){
    return sum.apply(this, arguments); //传入arguments 对象
}
function callSum2(num1, num2){
    return sum.apply(this, [num1, num2]); //传入数组
}
alert(callSum1(10,10)); //20
alert(callSum2(10,10)); //20

//传入arguments的各项,而不是对象
function sum(num1, num2){
    return num1 + num2;
}
function callSum(num1, num2){
    return sum.call(this, num1, num2);
}
alert(callSum(10,10)); //20
window.color = "red";
var o = { color: "blue" };
function sayColor(){
    alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue

Internet Explorer 9+, Firefox 4+, Safari 5.1+, Opera 12+ 和 Chrome。

window.color = "red";
var o = { color: "blue" };
function sayColor(){
    alert(this.color);
}
var objectSayColor = sayColor.bind(o);//函数的this值绑定到o
objectSayColor(); //blue

toLocaleString()和toString()各浏览器实现不同,不能依靠它返回重要信息。valueOf()简单返回函数本身。

基本封装类

  • Boolean 类型、Number 类型、String 类型
  • 与其它引用类型类似的功能
  • 与相应基础类型也有关联
var s1 = "some text";
s2 = s1.substring(2);基础类型展现了引用类型(对象)的行为

第二行现象是一种read模式,是一种值从内存中读取的模式,当进入读取模式时,内部发生了如下操作:
1. 创建String类型的实例
2. 调用实例的方法
3. 销毁(destory)实例

可以用下面的代码加以理解:

var s1 = new String("some text");
var s2 = s1.substring(2);
s1 = null;

此行为可以使得基础类型表现的如一个对象。
基本封装类型和引用类型的区别是声明周期。
如果你用new操作符实例化一个对象,在它离开作用域前一直存在于内存中。相反,自动创建的基础封装类型只存在一行代码就被销毁。所以,自动创建的基础封装类的属性和方法在运行期间是无法添加的。如下:

var s1 = "some text";
s1.color = "red";
alert(s1.color); //undefined

在第三行执行之前,String对象就被销毁了,第三行又重新创建了一个String对象,然而这个对象没有color属性。

Boolean类型

Number类型

String类型

var stringObject = new String("new String");

valueOf(), toLocaleString(), 和 toString()返回基础类型值。


其它方法:

//双字节字符也算作一个
var stringValue = "hello world";
alert(stringValue.length); //11
alert(stringValue.charAt(1)); //"e"

支持索引方法获取的浏览器:Internet Explorer 8 和 所有版本的Firefox, Safari, Chrome, Opera.

alert(stringValue[1]); //"e"
var stringValue = "hello ";
var result = stringValue.concat("world", "!");
alert(result); //"hello world!"
alert(stringValue); //"hello"
alert(result.slice(3)); //”lo world”
alert(result.substring(3)); //”lo world”
alert(result.substr(3)); //”lo world”
alert(result.slice(3, 7)); //”lo w”
alert(result.substring(3,7)); //”lo w”
alert(result.substr(3, 7)); //”lo worl”,第二个参数代表截取的个数
var stringValue = "hello world";
//截取位置:长度length + 负数参数
alert(stringValue.slice(-3)); //”rld”
//所有的负数参数都转换为0
alert(stringValue.substring(-3)); //”hello world”
//截取位置:长度length + 负数参数,第二个负数参数转化为0
alert(stringValue.substr(-3)); //”rld”
//截取位置:长度length + 负数参数
alert(stringValue.slice(3, -4)); //”lo w”
//所有的负数参数都转换为0,获取最小值0为起始位置
alert(stringValue.substring(3, -4)); //”hel”
//截取位置:长度length + 负数参数,第二个负数参数转化为0,即获取0个元素
alert(stringValue.substr(3, -4)); //”” (empty string)
-------------------------------------------------------------
// 注意:lastIndexOf从后往前找
// 起始和最后一个满足条件的位置
var stringValue = "hello world";
alert(stringValue.indexOf("o")); //4
alert(stringValue.lastIndexOf("o")); //7
// 第二个参数为起始搜寻位置,
alert(stringValue.indexOf(“o”, 6)); //7
alert(stringValue.lastIndexOf(“o”, 6)); //4
//应用
var stringValue = "Lorem ipsum dolor sit amet, consectetur adipisicing elit";
var positions = new Array();
var pos = stringValue.indexOf("e");
while(pos > -1){
    positions.push(pos);
    pos = stringValue.indexOf("e", pos + 1);
}
alert(positions); //"3,24,32,35,52"
-------------------------------------------------------------
//trim去掉首位的空字符
/*
Internet Explorer 9+,Firefox 3.5+, Safari 5+, Opera 10.5+, and Chrome. Firefox 3.5+, Safari 5+, and Chrome 8+ also support two nonstandard trimLeft() and trimRight() methods that remove white space only from the beginning or end of the string, respectively.
*/
var stringValue = " hello world ";
var trimmedStringValue = stringValue.trim();
alert(stringValue); //" hello world "
alert(trimmedStringValue); //"hello world"
-------------------------------------------------------------
var stringValue = "hello world";
alert(stringValue.toLocaleUpperCase()); //”HELLO WORLD”
alert(stringValue.toUpperCase()); //”HELLO WORLD”
alert(stringValue.toLocaleLowerCase()); //”hello world”
alert(stringValue.toLowerCase()); //"hello world"
字符串匹配模式
localeCompare() 方法
fromCharCode() 方法

HTML 方法

SINGLETON 内置对象

就如Object,Array 和String,这些变量不要用显示实例化,它们已经被初始化了,ECMA-262定义了新的内置对象 Global 和 Math。

Global

Global是JavaScript中特别的对象,因为它不能显示访问(explicitly accessible)。ECMA-262规定,凡是没有对象的方法和属性都是Global的方法和属性。全局定义的属性和方法都是Global的属性和方法。比如:isNaN(), isFinite(), parseInt(), 和 parseFloat()。还有一些其它的方法。

编码URI的方法

encodeURI()和encodeURIComponent()都是编码URI的方法。一个有效的URI是不能包含空格的,这些方法就把UTF-8编码的URI编码成能被浏览器识别的形式。
encodeURI()编码除了如冒号、正斜杠、问号、和“#”之外的所有URI。
encodeURIComponent()编码非标准的(非字母数字的)字符。

var uri = "http://www.wrox.com/illegal value.htm#start";
//"http://www.wrox.com/illegal%20value.htm#start"
alert(encodeURI(uri));
//"http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start"
alert(encodeURIComponent(uri));

相反

var uri = "http%3A%2F%2Fwww.wrox.com%2Fillegal%20value.htm%23start";
//http%3A%2F%2Fwww.wrox.com%2Fillegal value.htm%23start
alert(decodeURI(uri));
//http://www.wrox.com/illegal value.htm#start
alert(decodeURIComponent(uri));
eval()方法

eval() 如同一个解释器,将参数解释成一条语句,放到执行位置,代码成为了上下文的一部分,scope chain也是那段上下文。

var msg = "hello world";
eval("alert(msg)"); //"hello world"
eval("function sayHi() { alert('hi'); }");
sayHi();

因为在代码解析的时候eval()中的变量和函数都包含在字符串里,所以在eval()中的代码不能提升。它们在eval()执行的时候才被创建。

Global 对象的属性
Window 对象

尽管ECMA-262规定不能直接访问Global,但是浏览器用window实现了Global。所以s

var color = "red";
function sayColor(){
    alert(window.color);
}
window.sayColor(); //"red"

另一种获取Global方法:(下一章会继续讨论)

var global = function(){
    return this;
}();

Math对象属性

总结

在JavaScript中,对象被称为引用类型,一些内置类型可以被用来创建指定类型的对象。

  • 引用类型与传统面像对象的class类型,但是实现不同。
  • Object是基础,所有其他的引用类型都从它继承基础行为。
  • Array类型代表一个有序数列,可以操作和转化这些数值。
  • Date
  • RegExp
  • 函数
  • 基础封装
  • Global和Math