4.1 创建一个对象
var hero = {
name:"hero",
age:80,
say: function() {
return "I am a "+this.name;
}
}; // 类似OC里的字典
- 对象里包含的是一个个属性
- 属性也可以是函数,成为方法
访问对象属性
- 中括号表示法,如
hero['name']
. - 点号表示法,如
hero.name
.
调用对象方法
hero['say']();
hero.say();
修改属性与方法
- 增加:
hero.home = 'shanghai';
- 删除:
delete hero.home;
使用this
值
- 处于某个对象的方法内部时,可以用
this
访问当前对象
构造器函数
function hero(name) {
this.name = name;
}
var user1 = new hero("小明");
user1.name;
//打印数据:"小明"
- 这里的
hero
就是构造器函数 - 构造器函数的有点是可以在创建对象时接收一些参数
全局对象
- 程序所在的宿主环境会提供一个全局对象(如Web浏览器下的
Window
),而全局变量只是该对象的属性。 - 在构造器函数之外使用
this
关键字可以获得全局对象。
构造器属性
- 创建对象的同时会为其赋予一个特殊的属性 —— 构造器属性(
constructor property
)。 - 该属性实际上是一个只想用于创建该对象的构造器函数的引用。
instanceof
操作符
- 用来测试一个对象是不是由某个指定构造器函数所创建。
> function hero() {};
> var h1 = new hero();
> var h2 = {};
> h1 instanceof hero;
true
> h1 instanceof Object;
true
> h2 instanceof hero;
false
返回对象的函数
- 构造器默认返回的是
this
。 - 如果函数中有显示的返回,并且返回的是对象,这该构造器函数返回该对象。
- 如果其返回的是一个非对象类型,该构造器函数照常返回
this
。
传递对象
- 当我们拷贝某个对象或者将它传递给某个函数时,往往传递的都是该对象的引用,因此我们在引用上所做的任何改动,实际上都会影响它所引用的原对象。
比较对象
- 比较对象时,当且仅当两个引用指向同一个对象时结果为
true
4.2 内建对象
内建函数大致可以分为三类:
- 数据封装类对象:
Object、Array、Boolean、Number、String
- 工具类对象:包括
Math、Date、RegExp
- 错误类对象: 包括一般性错误对象以及其它各种特殊的错误类型
Object
- 是
JavaScript
中所有对象的父对象 - 创建一个空对象
var o = new Object();
o.constructor; // 返回构造器函数的引用
o.toString;// 返回对象的描述字符串
o.valueOf;// 通常返回对象本身
- 创建对象推荐使用
var o = {}
的形式(即对象文本标识法)
Array
-
Array()
是一个用来构建数组的内建构造器函数 - 通过
Array()
创建函数是可以传值,但如果传的是一个单独数字,会被认为是数组的长度 - 数组也是对象,但有些特殊之处:
- 数组的属性名从0开始递增,并自动生成数值
- 数组拥有一个用于记录元素数量的
length
属性 - 数组在父级对象的基础上扩展了更多额外的内建方法
-
push()
:在数组末端添加一个新元素,a.push('new')
相当于a[a.length]='new'
,返回改变后的数组长度。 -
pop()
:移除最后一个元素,a.pop()
相当于a.length--
,返回被移除的元素。 -
sort()
:排序,返回排序后的数组(改变了原数组)。 -
join()
:将数组以指定字符串拼接,返回拼接后的字符串。 -
slice()
:截取数组的一部分([1,2)
,包括前不包括后),不改变原数组。 -
splice()
:截取数组的一部分并用指定内容替换,改变原数组。
Function
- 请尽量避免使用
Function()
构造器定义函数 - 因为如果使用的话,就必须通过参数传递的方式来设定函数的参数名(通常使用字符串)以及函数体中的代码(也是用字符串)。
var sum = new Function('a','b','return a+b;');
函数对象的属性
-
constructor
:引用的是Function()
这个构造器函数 -
length
:用于记录函数声明时所决定的参数数量 -
prototype
- 指向了一个对象
- 只有在该函数是构造器时才发挥作用
- 该函数创建的所有对象都持有一个该
prototype
属性的引用
函数对象的方法
-
call()
和apply()
,每个函数都有这两个方法:- 可以用他们开触发函数,并指定相关的调用参数
- 可以让一个对象去‘借用’另外一个对象的方法,并为己所用
var obj = {
name: "A";
say: function(who) {
return 'hei ' + who + ', I am ' + this.name;
}
}
obj.say("B");
// hei B, I am A
var my_obj = {
name: "Gao";
}
obj.say.call(my_obj, "B");
// hei B, I am Gao
- 我们在调用
say()
函数的对象方法call()
时传递了两个参数 - 当
say()
被调用时,其中的this
被自动设置成了my_obj
对象的引用 - 如果需要传更多参数,在后面以此加入,用逗号隔开
- 如果没有传首参数或者传的是
null
,它的调用对象会默认为全局对象 -
apply()
的不同之处是,首参数后面的参数以数组的形式 -
arguments
实际上是对象,和数组的相似之处只有索引元素和length
属性两点,可以用call()
调用数组方法
[].slice.call(arguments);
Array.prototype.slice.call(arguments);
- 可以使用
Object
对象的toString()
方法,来区分对象和数组- 这个方法返回所创建对象的内部类名
Boolean
var b = new Boolean();
- 上面的
b
是一个对象 - 想将其转成基本数据类型的布尔值,可以调用它的
valueOf()
方法 - 不适用
new
操作符,Boolean()
可以将一些非布尔值转换为布尔值(相当于两次取反操作:!!value
) -
b
是对象,无论创建时传的是true
还是false
,返回值都是true
Boolean(new Boolean(false)); // 返回值为 true
Number
- 与
Boolean()
类似 - 内置属性:
Number.MAX_VALUE : 1.79769...
Number.MIN_VALUE : 5e-324
Number.POSITIVE_INFINITY : Infinity
Number.NEGATIVE_INFINITY : -Infinity
Number.NaN : NaN
String
- 基本数据类型
string
没有属性和方法,但使用过程中后台会床架String
对象,并在使用完后销毁,如"potato"[0]
Boolean(""); //返回 false
Boolean(new String("")); //返回 true
-
toUpperCase()
:小写字母转大写 -
toLowerCase()
:大写字母转小写 -
charAt()
:返回指定位置的字符(与[]
作用一样),如果位置不存在,返回空字符串 -
indexOf
:遇到匹配字符时返回第一次匹配位置的索引值,找不到对象,返回-1- 第二个参数传的是索引开始的位置
indexOf('o',2)
- 第二个参数传的是索引开始的位置
-lastIndexOf()
:搜索从末端开始,但返回的位置是从前端开始的
-
slice()
和substring()
:传起点位置(包括)和终点位置(不包括)slice(1,-1) === slice(1,s.length+(-1))
substring === substring(1,0)
split()
:将字符串根据指定字符串分割成数组join()
:将数组根据指定字符串拼接成新的字符串connect()
:在后面拼接字符串上面的方法都不会改动源字符串的值
Math
是全局对象,不是函数对象,所以不能用
new
操作符-
Math
的属性是不能修改的常数Math.PI : 3.1415926
Math.SQRT2 : 2的平方根
Math.LN2 : 0.693147 2的自然对数
Math.random
: 生成随机数,范围 0~1floor()
: 取小于或等于指定值的最大整数ceil()
: 取大于或等于指定值的最小整数round()
: 取最靠近指定值的整数max()
: 比较两个数取大的min()
: 比较两个数取小的pow(2,8)
: 2的8次方sqrt(9)
: 9的平方根
RegExp
-
正则表达式(
regular expression
),有以下两部分组成- 用于匹配的模式文本
- 0个或多个修饰符描述的匹配模式细节
-
RegExp
对象的属性-
global(g)
: 默认false
,只找第一个,设为true
则找出所有 -
ignoreCase(i)
: 是否忽略大小写,默认false
,不忽略 -
multiline(m)
: 是否跨行搜索,默认false
-
lastIndex
: 搜索开始的索引位,默认为0 -
source
: 用于存储正则表达式匹配模式
-
-
RegExp
对象的方法-
test()
: 返回查找的结果,布尔值 -
exec()
: 返回所有匹配的字符串的数组
-
/j.*t/.test("JavaScript"); // 返回false, 因为大小写
/j.*t/i.test("JavaScript"); // 返回true
/j.*t/i.exec("JavaScript")[0]; // 返回"JavaScript"
- 以正则表达式为参数的字符串方法
-
match()
: 返回包含匹配内容的数组 -
search()
: 返回第一个匹配内容所在的位置
-
var s = new String('HelloJavaScript');
s.match(/a/); // ["a"]
s.match(/a/g); // ["a","a"]
s.match(/j.*a/i); // ["Java"]
s.search(/j.*a/i); // 5
-
replace()
: 将匹配的文本替换成指定字符串- 可以用
$&
替代所找到的匹配文本 - 如果正则表达式中分了组(即带括号),可以用
$1
代表第一组,$2
代表第二组,以此类推
- 可以用
s.replace(/[A-Z]/g,'_'); // _ello_ava_cript , 将大写字母换成下划线
s.replace(/[A-Z]/g,'_$&'); // _Hello_Java_Script , 将大写字母换成下划线加大写字母
s.replace(/([A-Z])/g,'_$1'); // _Hello_Java_Script, '$1'代表前面第一个括号内匹配到的大写字母
// 注意下面的写法,通过邮箱地址截取用户名
var email = "[email protected]";
var username = email.replace(/(.*)@.*/,"$1");
// username 的值为 "GaoSir"
// "$1"代表第一组匹配的"GaoSir",并用该值替换整个正则表达式匹配到的内容
- 回调式替换
var re = /(.*)@(.*)\.(.*)/; // "\.","."需要转义字符"\"修饰
var callback = function() {
a = arguments;
return a[1] + " ~~ " + a[2] + " -- " + a[3];
};
email.replace(re,callback);
// 结果为 ""GaoSir ~~ xxx -- com""
a;
// 结果为 ["[email protected]", "GaoSir", "xxx", "com", 0, "[email protected]"]
- `replace()`会给回调函数传一系列参数
- 首参数是正则表达式所匹配的内容
- 尾参数是被搜索的字符串
- 尾参数之前的参数是匹配内容所在的位置
- 剩下的参数可以是由`regex`模式所分组的所有匹配字符串数组
-
split()
: 根据指定的正则表达式将目标字符串分割成若干个数组元素
var c = "one, two , three,four"; // 注意空格
c.split(","); // ["one"," two "," three","four"]
//如果想过滤掉多余的空格
c.split(/\s*,\s*/); // ["one","two","three","four"]
// "\s*"表示任意多个空格
4.4 练习题
4.在String()构造函数不存在的情况下自定义一个MyString()的构造器函数。
5.更新上面的MyString()构造器,为其添加一个reverse()方法。
function MyString(pstr){
this.str=pstr.toString();
this.length=this.str.length;
for(var i=0;i
6.在Array()构造器以及相关的数组文本标识法都不存在的情况下,自定义一个类似的MyArray()构造器。
function MyArray(){
this.length=arguments.length;
for(var i=0;i