1、对象
⑴ 概念
因为基本数据类型(string、number、boolean、null、undefined),都是单一的值,它们之间没有任何的联系。所以为了让它们成为一个整体,才使用引用数据类型(object)⑵ 分类
① 内建对象
由ES标准中定义的对象,在任何的ES的实现中都可以使用 例如:String、Math、Function等② 宿主对象
由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象(BOM、DOM) 例如:console、document③ 自定义对象
由开发人员自己创建的对象2、创建对象
var obj = new Object();
使用new 关键字所调用的函数,是构造函数
构造函数就是专门用来创建对象的函数
var obj = new Object();
console.log(typeof obj); // object
console.log(obj); // Object {}
3、对象的属性
⑴ 给对象添加属性(修改属性值)
对象.属性名 = 属性值;
注意:如果使用特殊的属性名,需要通过
对象['属性名'] = 属性值;
来操作对象
⑵ 读取对象的属性
对象.属性名;
或
对象['属性名'];
注意:如果对象的属性不存在,则会返回undefined
⑶ 删除对象的属性
delete 对象.属性名
⑷ 属性名和属性值的规范
对象的属性名虽然不强制要求遵循字符串标识符的规范,即什么名字也可以起,但是在定义时还是要尽量按照字符串标识符的规范来 对象的属性值可以是任意数据类型,包括object⑸ in 运算符
可以使用属性名 in 对象
来判断某一个属性是否属于对象,该表达式返回的是boolean类型
示例:
var obj = new Object();
obj.name = '张三';
obj['age'] = 14;
console.log('name' in obj); // true
console.log('age' in obj); // true
console.log('gender' in obj); // false
4、基本数据类型和引用数据类型
先看一个例子:var i = 10;
var j = i;
console.log(i); // 10
console.log(j); // 10
j = 11;
console.log(i); // 10
console.log(j); // 11
console.log();
var obj = new Object();
obj.name = '张三';
var obj2 = obj;
console.log(obj.name); // 张三
console.log(obj2.name); // 张三
obj2.name = '李四';
console.log(obj.name); // 李四
console.log(obj2.name); // 李四
JS中的基本数据类型都是保存在栈内存当中的,变量与变量之间是独立存在的,所以修改一个变量不会影响到其他的变量
而对象则是保存在堆内存当中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,而变量保存的是对象的内存地址值(对象的引用),如果两个变量保存的是同一个对象,则修改其中任意一个,另外一个也会跟着被改变
5、对象字面量
创建对象:var obj = {};
通过这种方式所创建的对象,和通过new Object();所创建的对象,是一样的
创建对象,并指定属性
var obj = {
属性名1 = 属性值,
属性名2 = 属性值
};
注意:
⑴ 对象的属性名可以加引号,也可以不加,建议不加,如果要使用特殊的属性名,则必须添加引号
⑵ 每个属性名和属性值之间使用逗号隔开,最后一个名值对的后面就不要再添加逗号了
6、函数【一】
⑴ 概念
函数也是一个对象,它可以封装一些代码,并在需要的时候执行这些代码⑵ 创建函数对象
① 空的函数体对象
var fn = new Function();
console.log(fn); // function anonymous() { }
console.log(typeof fn); // function
② 以字符串的形式传递给函数的构造函数
var fn = new Function('console.log("Hello!")');
console.log(fn); // function anonymous() { console.log("Hello!") }
⑶ 调用函数
函数名([实参1, 实参2, ...]);fn(1, 2);
⑷ 使用函数声明来创建函数
function 函数名([形参1, 形参2, ...]) {
函数体
}
例如:
function hello() {
console.log('hello!');
}
⑸ 使用函数表达式来创建函数
var 函数名 = function([形参1, 形参2, ...]) {
函数体
};
注意分号
例如:
var hello = function() {
console.log('hello!');
};
7、函数【二】
⑴ 函数的参数
function fn(a, b) { }
在函数的括号中指定一个或多个形式参数(形参),多个形参之间用逗号隔开
声明形参就相当于在函数的内部声明了对应的变量,但是并不赋值
function fn(a) {
console.log(a);
}
function fn() {
var a;
console.log(a);
}
fn(10);
在调用函数时,可以在括号中指定实际参数(实参),而实参则会赋值给函数中对应的形参
function fn() {
var a = 10;
console.log(a); // 10
}
需要注意的是,调用函数时,函数解析器并不会检查实参的类型,所以需要注意接收到的实参是否合法,必要时可以进行类型检查
同时函数解析器也不会检查实参的数量,多余的实参并不会被赋值;如果实参数量少于形参数量,则没有实参对应的形参将会是undefined
function sum(a, b) {
// console.log(b);
console.log(a + b);
}
sum(true, undefined); // NaN
sum(1, 2); // 3
sum(1, 2, 3); // 3
sum(10); // NaN 【b是undefined】
函数的实参可以是任意类型,包括对象
示例1:
function hi(obj) {
console.log('姓名: ' + obj.name + ', 年龄: ' + obj.age);
}
var obj = {
name: '张三',
age: 14
};
hi(obj);
示例2:
function fn(fun) {
fun();
}
var fun = function() {
console.log('Hello!');
};
fn(fun);
⑵ 函数的返回值
使用return 返回值; 来设置函数的返回值,返回值可以是任意类型注意:① 如果return后面不跟任何值就相当于返回一个undefined;② 如果不写return,则也会返回一个undefined;③ return语句一旦执行,则之后的代码不会被执行
示例1:
function fn() {
return 'hello';
}
var result = fn();
console.log(result); // hello
function fun() {}
result = fun();
console.log(result); // undefined
function fn2() {
return;
}
result = fun();
console.log(result); // undefined
示例2:
function fun() {
var fn = function() {
console.log('hello');
};
return fn;
}
var result = fun();
console.log(result); // function () { console.log('hello'); }
result();
fun()();
示例3:
function fn() {
console.log(1);
return 2;
console.log(3); // 不会被执行
}
console.log(fn());
⑶ 立即执行函数
(function([形参1, 行参2, ...]) {
函数体
})([实参1, 实参2, ...]);
函数定义完就立即被调用,这种函数往往只会执行一次
示例:
(function(a, b) {
console.log(a + b);
})(1, 2);
8、方法
因为对象的属性可以是对象,所以它也可以是一个函数,而这个函数被称为对象的方法。这只是名称上的区别var obj = {
sayHello: function() {
console.log('Hello!');
}
};
枚举对象的属性
for (var 变量名 in 对象名) {
// 这里的变量名就是对象的每个属性名
// 使用 对象名[变量名(属性名)] 来获取对象的属性值
}
对象有几个属性,就会循环几次;每次循环都会把对象的一个属性名赋值给变量
示例:
var obj = {
name: '张三',
age: 14,
gender: '男'
};
for (var key in obj) {
console.log(key + ':' + obj[key]);
}
结果:
name:张三
age:14
gender:男
9、作用域
作用域指一个变量的作用范围,JS有2种作用域:全局作用域和函数作用域⑴ 全局作用域
- 直接写在script标签中的JS代码,都在全局作用域中
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 全局作用域中有一个全局对象:window,它代表了一个浏览器的窗口,它由浏览器创建,可以直接使用它
- 全局作用域中所创建的变量都会作为window对象的属性来保存,创建的函数都会作为window对象的方法
- 全局作用域中的变量都是全局变量,可以在页面的任意位置访问到
示例:
var a = 10;
function abc() {
console.log('ABC');
}
console.log(a); // 10
console.log(window.a); // 10
abc(); // ABC
window.abc(); // ABC
⑵ 变量的声明提前
使用var 关键字声明的变量,会在所有的代码执行之前被声明,但是不会被赋值,值是undefined 但是声明变量时不使用var 关键字,则变量的声明不会被提前示例:
console.log(a); // undefined
var a = 10;
console.log(b); // Uncaught ReferenceError: b is not defined
b = 123;
⑶ 函数的声明提前
使用函数声明形式所创建的函数function 函数名(){}所创建的函数,会在所有的代码执行前就被创建,所以可以在函数声明前调用函数 如果使用函数表达式创建函数,不会被提前声明,所以不能在声明之前就调用示例:
hello(); // hello
function hello() {
console.log('hello');
}
hi(); // Uncaught TypeError: hi is not a function
var hi = function() {
console.log('hi');
};
⑷ 函数作用域
- 调用函数时创建函数作用域,函数执行完毕后,函数作用域被销毁
- 每调用一次函数,就会创建一个新的函数作用域,它们之间是相互独立的
- 在函数作用域中可以访问到全局作用域中的变量;而在全局作用域中无法访问到函数作用域中的变量
- 当在函数作用域中操作(访问)一个变量时,会现在自身作用域中寻找,找到就直接使用;找不到会到上一级作用域中寻找,直到找到全局作用域,如果全局作用域中仍然没有,则会报错:Uncaught ReferenceError
示例:
var a = 1000;
function fun() {
var a = 100;
function fn() {
var a = 10;
console.log(a); // 10
}
fn();
}
fun();
var a = 1000;
function fun() {
var a = 100;
function fn() {
console.log(a); // 100
}
fn();
}
fun();
var a = 1000;
function fun() {
function fn() {
console.log(b); // Uncaught ReferenceError: b is not defined
}
fn();
}
fun();
在函数作用域中同样有声明提前的特性,使用var 关键字声明的变量会在函数中所有的代码执行被声明;函数声明也会在函数中所有的代码执行之前执行
在函数中没有使用var 声明的变量都会成为全局变量
示例:
function fn() {
console.log(a); // undefined
var a = 10;
hello(); // hello
function hello() {
console.log('hello');
}
console.log(hi); // undefined
var hi = function() {
console.log('hi');
};
b = 100; // window.d = 100;
}
fn();
console.log(b); // 100
console.log(a); // Uncaught ReferenceError: a is not defined
var a = 10;
function fn() {
console.log(a); // undefined
var a = 100;
}
fn();
console.log(a); // 100
function fun() {
console.log(b); // Uncaught ReferenceError: b is not defined
b = 10;
}
fun();
10、this
JS解析器在调用函数时,每次都会向函数内部传入一个隐含参数,这个参数就是this,它指向的是一个对象,这个对象被称之为函数执行的上下文对象 根据函数的调用方式的不同,this会指向不同的对象:①以函数形式调用,this指向window;②以方法形式调用,this指向方法所属的对象示例:
function fn(obj) {
console.log(this);
}
fn(); // [object Window]
var z3 = { name: '张三', fun: fn };
var l4 = { name: '李四', fun: fn };
console.log(z3.fun == fn); // true
z3.fun(); // [object Object]
l4.fun(); // [object Object]
var name = '窗口';
function fn() {
console.log(this.name);
}
var z3 = { name: '张三', fun: fn };
var l4 = { name: '李四', fun: fn };
fn(); // 窗口
z3.fn(); // 张三
l4.fn(); // 李四
11、工厂方法【this的应用】
function createFn(name, age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.hi = function() {
console.log(this.name + '[' + this.age + ']');
};
return obj;
}
var z3 = createFn('张三', 14);
var l4 = createFn('李四', 12);
z3.hi(); // 张三[14]
l4.hi(); // 李四[12]
12、JSON
⑴ 概念
JavaScript Object Notation,JS对象表示法由于JS中的对象,只有JS能识别,其他语言都不认识。JS为了能和其他语言交互,就需要通过JSON来实现
JSON本质上就是一个字符串
它和JS对象的格式一样,不同的是:在JSON字符串中的属性名必须加双引号,其他的和JS语法一致
分类:① 对象 {};② 数组 []
例如:
① '{"name": "张三", "age": 14}'
② '[1, true, "hi"]'
注意:JSON中的引号必须使用双引号,否则在转换为对象时,会报解析错误
JSON中允许的值的类型:
① 字符串
② 数值
③ 布尔
④ null
⑤ 普通对象
⑥ 数组
⑵ 工具类
JS提供了一个工具类:JSON,它有2个方法parse和stringify① parse
将JSON字符串转换为一个JS对象② stringify
将JS对象转换为一个JSON字符串示例:
var z3 = {
name: '张三',
age: 14,
flag: true,
gender: null,
pet: {
name: '旺旺',
type: 'dog'
},
cities: ['北京', '上海', '深圳']
};
console.log(z3); // Object {name: "张三", age: 14, flag: true, gender: null, pet: Object {name: "旺旺", type: "dog"}, cities: Array(3) ["北京", "上海", "深圳"]}
var json = JSON.stringify(z3);
console.log(typeof json); // string
console.log(json); // {"name":"张三","age":14,"flag":true,"gender":null,"pet":{"name":"旺旺","type":"dog"},"cities":["北京","上海","深圳"]}
var obj = JSON.parse(json);
console.log(obj); // Object {name: "张三", age: 14, flag: true, gender: null, pet: Object {name: "旺旺", type: "dog"}, cities: Array(3) ["北京", "上海", "深圳"]}
注意:JSON工具类在IE7及以下版本中不支持(SCRIPT5009: “JSON”未定义)
解决办法:
① 调用eval函数
eval函数用于将一段字符串当成JS代码来执行,并返回执行结果
如果传入eval的字符串中含有{ },它会将其当作是代码块。可以在字符串的两端加上( ),表示这是一个整体
例如:
var script = 'alert("你好!");';
var result = eval(script);
console.log(result); // undefined
var json = '{"name":"李四","age":14,"flag":true}';
var obj = eval('(' + json + ')');
console.log(typeof obj); // object
console.log(obj); // Object {name: "李四", age: 14, flag: true}
但这样做一方面执行效率差;另一方面也不安全,因为无法保证执行的字符串不是一段恶意代码
② 引入外部JSON扩展工具js文件【json2.js】
GitHub链接:JSON-js