对象
JS中的数据类型
- String 字符串
- Number 数值
- Boolean 布尔值
- Null 空值
- Undefined 未定义
以上五种类型属于基本类型,只要不是以上五种,都是对象
- Object 对象
基本数据类型都是单一的值,值和值之间没有任何联系
在JS中用来表示一个人的信息(name gender age)
var name="张三";
var gender="男";
var age="18";
如果使用基本数据类型,创建的变量都是独立的,不能成为一个整体
对象属于一种复合的数据,在对象中可以保存多个不同数据类型的属性
一、对象的分类
1、内建对象
- 由ES标准中定义的对象,在任何的ES的实现中都可以使用
- 比如:Math String Number Boolean Function Object……
2、宿主对象
- 由JS的运行环境提供的对象,主要由浏览器提供的对象
- 比如:BOM(浏览器对象模型) DOM(文档对象模型)
console.log();
document.write();
//都是由浏览器提供
3、自定义对象
- 由开发人员自己创建的对象
二、创建对象
1、 使用 new 关键字调用的函数,是构造函数constructor
2、 构造函数是专门用来创建对象的函数
3、 使用typeof来检查一个对象时,会返回object
- 在对象中保存的值称为属性
- 向对象添加属性,语法:
对象.属性名=属性值;
var obj = new Object();
//console.log(typeof obj);
//向obj添加一个name属性
obj.name="张三";
//向obj添加一个gender属性
obj.gender="男";
//向obj添加一个age属性
obj.age="18";
console.log(obj);
var obj = new Object();
//向obj添加一个name属性
obj.name="张三";
//向obj添加一个gender属性
obj.gender="男";
//向obj添加一个age属性
obj.age="18";
console.log(obj.name);//输出“张三”
var obj = new Object();
//向obj添加一个name属性
obj.name="张三";
//向obj添加一个gender属性
obj.gender="男";
//向obj添加一个age属性
obj.age="18";
//修改obj的name属性值
obj.name="孙悟空"
console.log(obj.name);//输出“孙悟空”
var obj = new Object();
//向obj添加一个name属性
obj.name="张三";
//向obj添加一个gender属性
obj.gender="男";
//向obj添加一个age属性
obj.age="18";
//删除obj的name属性值
delete obj.name;
console.log(obj.name);//没有该值,输出undefined
三、属性名和属性值
1、属性名
- 对象的属性名不强制要求遵守标识符的规范
- 尽量按照标识符的规范设置
- 如果使用特殊的属性名,不能采用.的方式来操作
- 需要使用另一种方式,语法:
对象["属性名"]=属性值;
- 读取时也需要采用这种方式
- 使用[]这种形式去操作属性更加灵活
- 在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性
var obj = new Object();
obj["123"]=567;
obj["nihao"]="你好";
var n = "nihao"
console.log(obj["123"]);
console.log(obj[n]);
2、属性值
JS对象的属性值,可以是任意的数据类型, 甚至也可以是一个对象
- 通过该运算符可以检查一个对象中是否含有制定的属性,有返回true,没有则返回false
- 语法:"属性名" in 对象
var obj = new Object();
obj.name="孙悟空";
obj.test= true;
obj.test= null;
obj.test= undefined;
var obj2 = new Object();
obj2.name="猪八戒";
obj.test=obj2;
console.log(obj.test);//返回 name=“猪八戒”
console.log(obj.test.name);//返回 “猪八戒”
console.log("name" in obj);//返回true
四、基本、引用数据类型
(一)基本数据类型
String Number Boolean null Undefined
- 基本数据类型的值直接在栈内存中存储
- 值与值之间是独立存在的,修改一个变量不会影响其他变量
var a = 123;
var b = a;
a++;
console.log("a"= +a); //输出为124
console.log("b"= +b); //输出为123
(二)引用数据类型
对象:Object
- 对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟一个新的空间
- 而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用
- 当通过一个变量修改属性时,另一个也会受到影响
var obj = new Object();
obj.name = "孙悟空";
var obj2 = obj;
console.log(obj.name);//输出 孙悟空
console.log(obj2.name);//输出 孙悟空
//修改obj的name属性
obj.name = "猪八戒";
console.log(obj.name);//输出 猪八戒
console.log(obj2.name);//输出 猪八戒
obj2 = null;
console.log(obj);//输出 Object
console.log(obj2);//输出 null
- 当比较两个基本数据类型的值时,就是比较他们的值
- 当比较两个引用数据类型时,是比较对象的内存地址
如果两个对象一模一样,但是地址不同,它也会返回false
var a = 10;
var b = 10;
console.log(a == b); // 返回true
var obj3 = new Object();
var obj4 = new Object();
obj3.name = "沙和尚";
obj4.name = "沙和尚";
console.log(obj3 == obj4); // 返回false
五、对象字面量
使用对象字面量,可以在创建对象时,直接指定对象的属性
语法: {属性名:属性值,属性名:属性值....}
- 对象字面量的属性名可以加引号也可以不加, 建议不加
- 如果要使用一些特殊的名字,则必须加引号
- 属性名和属性值是一组一组的名值对结构
- 名和值之间使用冒号
:
连接多对名值之间使用逗号,
隔开 - 如果一个属性之后没有其他属性时, 就不要写逗号
,
了
//创建一个对象
//var obj = new Object();
//使用对象字面量来创建一个对象
var obj = {};
obj.name = "孙悟空";
var obj2 = {
name:"猪八戒",
age:28,
gender:"男"
test:{
name:"沙和尚",
age:27
}
};
console.log(obj2.test);//输出name:沙和尚 age:27
函数
一、函数的简介
函数(function):也是一个对象
- 普通对象只能封装属性
- 函数对象可以封装一些功能(代码),在需要时可以执行这些功能
- 函数可以保存一些代码在需要时调用
- 使用typeof检查一个函数时会返回function
1、使用构造函数的方式来创建函数
- 可以将要封装的代码以字符串的形式传递给构造函数
- 封装到函数中的代码不会立即执行
- 函数中的代码会在函数调用的时候执行
- 调用函数,语法:
函数对象()
- 当调用函数时,函数中封装的代码会按照顺序执行
在实际开发中很少使用构造函数来创建一个函数
var fun = new Function(
"console.log('这是我的第一个函数');"
);
fun.hello = "你好";
console.log(fun.hello);//输出 你好
fun();//输出 这是我的第一个函数
2、使用函数声明来创建一个函数
语法:
中括号可选,可不写
function 函数名([形参1,形参2,形参n]){
语句...
}
function fun2(){
console.log("这是我的第二个函数");
alert("哈哈哈哈");
document.write("你好");
}
fun2();//按顺序输出3个函数
3、使用函数表达式来创建一个函数
语法:
var 函数名 = function([形参1,形参2,形参n]){
语句...
}
将一个匿名函数赋值给一个变量
var fun3 = function (){
console.log("这是一个匿名函数");
}
fun3();
二、函数的参数
1、形参与实参
可以在函数的()中来指定一个或多个形参(形式参数)
- 多个形参之间使用
,
隔开,声明形参就相当于在函数内部声明了对应的变量,但是 并不赋值 - 在函数调用时,可以在()中指定实参(实际参数)
- 实参将会赋值给函数中对应的形参
- 调用函数时解析器不会检查实参的类型(可能会存在非法参数)
- 调用函数时解析器也不会检查实参的数量(多余实参不会被赋值)
- 函数的实参可以是任意的数据类型
- 如果实参的数量少于形参的数量,则没有对应实参的形参将会是undefined
function sum(){
var a = 1;
var b = 1;
console.log(a+b);
}
sum(); // 输出 求和值2
//a,b都是形参
function sum (a,b){
cosole.log(a+b+c);
}
//1,2都是实参,实参可以是任意数据类型
sum(1,2);//输出 求和值3
//3没有对应的形参,将变为undefined
sum(1,2,3);//输出 求和值null
2、函数的返回值
可以使用return来设置函数的返回值
语法: return 值
- return后的值将会作为函数的执行结果返回
- 可以定义一个变量来接受该结果
- 在return后的语句不会再执行
- 如果return语句后不跟任何值就相当于返回一个undefined
- 函数中不写return也会返回undefined
function sum(a,b,c){
// alert(a+b+c);
var d = a+b+c;
return d;
//return;
alert("hello");
}
//调用函数
// sum(1,2,3)
//变量result的值就是函数的执行结果
//函数返回什么result的值就是什么
var result = sum(4,7,8);
console.log("result="+result);//输出 求和值19
3、实参的类型
例1: 定义一个函数,判断一个数字是否为偶数,如果是返回true,否则返回false
function isOu(num){
if(unm % 2 == 0){
return true;
}else{
return false;
}
//相等于上面的式子
return num % 2 == 0 ;
}
var result = isOu(2);
console.log("result = "+result);//输出true
例2: 定义一个函数,可以根据半径计算一个圆的面积,并返回计算结果
function mianji(r){
return 3.14*r*r;
}
var result = mianji(10);
console.log("result = "+result);//输出314
例3: 创建一个函数,可以在控制台输出一个人的信息
实参可以是任意的数据类型,也可以是一个对象
- 当参数过多时,可以将参数封装到一个对象中,然后通过对象传递
function sayHello(o){
console.log("我是"+o.name+",今年我"+o.age+"岁了,"+"我是一个"+o.gender+"人,我住在"+o.address);
}
//创建一个对象
var obj = {
name:"孙悟空",
age:18,
address:"花果山",
gender:"男"
};
sayHello(obj);
例4: 实参可以是一个对象,也可以是一个函数
fun(sayHello)
函数对象,相当于直接调用函数对象fun(sayHello())
调用函数,相当于使用函数的返回值
function sayHello(o){
console.log("我是"+o.name+",今年我"+o.age+"岁了,"+"我是一个"+o.gender+"人,我住在"+o.address);
}
//创建一个对象
var obj = {
name:"孙悟空",
age:18,
address:"花果山",
gender:"男"
};
function fun(a){
console.log("a = "+a);//输出sayHello整个函数
a(obj);//输出sayHello(obj);的结果
}
fun(sayHello);
fun(sayHello());//输出函数sayHello的返回值
4、返回值的类型
function fun(){
alert("函数要执行了");
for(var i=0; i<5; i++){
console.log(i);
if(i == 2){
break;//break可以退出当前循环
continue;//用于跳过当次循环
return;//可以结束整个函数
}
console.log(i);
}
alert("函数执行完了");
}
fun();
- 返回值可以是任意数据
- 可以是对象,也可以是一个函数
function fun2(){
//var obj = {name:"沙和尚"};
//return obj;
return {name:"沙和尚"};
}
var a = fun2();
console.log("a="+a.name);
function fun3(){
//在函数内部再声明一个函数
function fun4(){
alert("我是fun4");
}
//fun4();
return fun4;//fun4函数作为返回值返回
return fun4();
}
//a = fun3();
//console.log(a);
//a();
fun3()();
5、立即执行函数
- h函数定义完成立即被调用,这种函数叫做立即执行函数
- 立即执行函数一般只会执行一次
(function(){
alert("我是一个匿名函数");
})();
(function(a,b){
console.log("a = "+a);
console.log("b = "+b);
})(123,456);
6、对象的方法
对象的属性值可以是任意数据内心,也可以是一个函数
- 如果一个函数作为一个对象的属性保存,那么这个函数就是这个对象的方法
- 调用这个函数就是调用对象的方法(method)
- 但是它只是名称上的区别,没有其他区别
var obj = new Object();
obj.name = "孙悟空";
obj.age = 18;
obj.sayName function(){
console.log(obj.name);
};
function fun(){
console.log(obj.name);
}
//console.log(obj.sayName);
//调用obj的sayName方法
obj.sayName();
//调用函数
fun();
var obj2 = {
name:"猪八戒",
age:18,
sayNme:function(){
console.log(obj2.name);
}
};
obj2.sayName();
7、枚举对象中的属性
使用 for...in
语句来枚举对象中的属性
语法:
for(var 变量 in 对象){
}
for...in
语句,对象中有几个属性,循环体就会执行几次- 每次执行时会将对象中的一个属性的名字赋值给变量
var obj = {
name:"孙悟空",
age:18,
gender:"男",
address:"花果山"
};
//[]可以传变量
for(var n in obj){
console.log("属性名:"+n);
console.log("属性值:"+obj[n]);
}
三、作用域
- 作用域指一个变量的作用的范围
- 在JS中共有两种作用域
- 1、全局作用域
- 2、函数作用域(区域作用域)
(一)全局作用域
- 直接编写在script标签中的Js代码,都在全局作用域
- 全局作用域在页面打开时创建,在页面关闭时销毁
- 在全局作用域中有一个全局对象window(代表的是一个浏览器的窗口,由浏览器创建,可以直接使用)
- 在全局作用域中,创建的变量都会作为window对象的属性保存
- 在全局作用域中,创建的函数都会作为window对象的方法保存
- 全局作用域中的变量都是全局变量,在页面的任意部分都可以访问的到
function fun(){
var a = 123;
}
fun();
console.log(a);//报错
var a = 10;
var b = 20;
var c = "hello";
console.log(window.c);//输出hello
function fun(){
console.log("我是fun函数");
}
window.fun();//与下面效果相同
fun();
1、变量的声明提前
- 使用var关键字声明的变量,会在所有的代码执行之前被声明(但是不会赋值)
- 但是如果声明变量时不使用var关键字,则变量不会被声明提前
var a;
console.log("a = "+a);
var a = 123;
2、函数的声明提前
- 使用函数声明形式创建的函数function 函数(){},它会在所有的代码执行之前就被创建, 可以在函数声明前调用函数
- 使用函数表达式创建的函数,不会被声明提前,所有不能在声明前调用
var fun();//已经赋值
fun();//输出我是fun函数
var fun2;//没有赋值
fun2();//报错,不存在fun2()函数
//函数声明,会被提前创建
function fun(){
console.log("我是fun函数");
}
//函数表达式,不会被提前创建
var fun2 = function(){
console.log("我是fun2函数");
}
(二)函数作用域(区域作用域)
- 调用函数时创建函数作用域,函数执行完毕后函数作用域销毁
- 每调用一次函数,就会创建一个新的函数作用域,他们时=是互相独立的
- 在函数作用域中可以访问到全局作用域的变量,在全局作用域无法访问到函数作用域的变量
- 当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用,如果没有就向上一级作用域中寻找,直到找到全局作用域,如果全局作用域也没用就会报错
- 在函数中想要访问全局域中的变量可以使用window对象
var a = 10;
function fun(){
var a = "我是函数中的变量a";
var b = 20;
//console.log("a = "+a);
function fun2(){
console.log("a = "+window.a);
}
fun2();
}
fun();
console.log("a = "+a);
在函数作用域中也有声明提前的特性
- 使用var关键字声明的变量,会在函数中所有代码执行前被声明(不会被赋值)
- 函数声明也会在函数中所有代码执行前被创建
- 在函数中不使用var声明的变量都会变成全局变量
- 定义形参就相当于在函数作用域中声明了变量
function fun3(){
fun4();
console.log(a);
var a = 35;
function fun4(){
alert("我是fun4");
}
}
fun3();
var c = 33;
function fun5(){
console.log("c = "+c);
var c = 10;
//没有var关键字,则会变为全局变量,相当于window.d
d = 100;
}
fun5();
//在全局输出c
console.log("d = "+d);
//定义形参就相当于在函数作用域中声明了变量
function fun6(e){
alert(e);
}
fun6();
四、debug
alert(c);
var a = 10;
var b = "hello";
c = true;
function fun(){
alert("hello");
}
var d = 35;
使用浏览器F12检查功能进行debug检查
评论 (0)