JavaScript(四)[对象、函数、作用域、变量提升]

目录导航


对象 (Object)

1.1 对象

基本数据类型都是一个一个独立的值,值与值之间不存在任何的联系。这样就导致无法在程序中表示一些复杂的数据。
基本数据类型(不可变类型)

  • 字符串(string)
  • 数值(number)
  • 布尔值(Boolean)
  • 空值(null)
  • 未定义(undefined)

复杂数据类型

  • 对象(Object)

对象就是 JS 中的一种数据类型。
对象相当于是一个容器(复杂数据类型),在对象中可以存储不同类型的数据
对象中存储的数据被称为属性,向对象中添加数据称为添加属性

//创建一个空的对象
var obj = new Object();  //var obj = Object();  是一样的,new可以省略
console.log(obj);    // {}

//向对象中添加属性:
//	对象.属性名 = 属性值;

obj.name = "孙悟空";
obj.age = 18;
obj.gender = "男";
console.log(obj);   //{name:"孙悟空",age:18,gender:"男"}

//读取对象中的属性:
//	  对象.属性名

console.log(obj.name);     // 孙悟空
console.log(obj.age);      // 18
console.log(obj.gender);   // 男
console.log(obj.address);  //undefined  当我们访问一个对象中没有的属性时,不会报错而是返回undefined

//删除属性
//    delete   对象.属性名
delete obj.name;
console.log(obj.name);   //  undefined

1.2 属性

1.2.1 属性名

属性名:
	对象的属性是任意值,不必要遵循标识符的规范(不推荐)。尽量遵循标识符的规范。
var obj = Object();
obj.name = "孙悟空";
console.log(obj.name);  //孙悟空
特殊的命名方式: 
   对象["属性名"] = 属性值
obj.12312!@#@#!sdasdasff = "孙悟空";     //这样命名导致报错
obj.["12312!@#@#!sdasdasff"] = "孙悟空";  // 这样就可以成功   (不推荐这样使用)
读取属性的第二种方式:
	对象['属性名']     // 这种方式读取属性更加灵活
console.log(obj.["12312!@#@#!sdasdasff"]);   // 孙悟空
console.log(obj.["name"]);                   // 孙悟空

灵活例子:
var obj = object();
obj.name = "孙悟空";
obj.age = 18;
obj.gender = "男";
var a = "name";
console.log([a]);   // 孙悟空
var a = "age";
console.log([a]);   // 18
//根据变量的值不同  读取的结果也不一样。注意:[a] 不能变成 ["a"],["a"]就变成读取对象中的a属性

1.2.2 属性值

对象的属性值可以是任意的数据类型

obj.test = null;
obj.test = true;
obj.test = "字符串";
obj.test = 123456;
obj.test = Object();

1.2.3 属性枚举

var obj = Object();
obj.name = "孙悟空";
obj.age = 18;

//在开发中对象可能是读取来的,不知道对象里有什么属性
//检查一个对象中是否有某个属性
// in  运算符   用来检查对象是否有某个属性
// 有符号 true   没有返回false
语法:
	'属性名' in 对象

console.log('name' in obj);     // true

//而枚举就是将对象中的属性全部提取出来,对象中有几个属性就会执行几次
	//每次执行都会将一个属性赋值给我们定义的变量
语法:
	for (var 变量 in 对象){
	语句...
}


for(var n in obj){
	console.log(n);  // 见下图1
}

//当需要属性值时
for(var n in obj){
	console.log(obj.n);  // 见下图2
}
// obj.n 表示去读取 obj 中 n 的属性,但是 obj 中没有 n 的属性所以是 undefined
//虽然在 for in 中每一次循环会把属性赋值给 n ,但 n 是一个变量

for(var n in obj){
	console.log(obj.[n]);  // 见下图3
}

在这里插入图片描述

1.3 对象字面量

var obj = Object();
var obj = new Object();
都是创建一个对象
以字面量来创建对象:
	var obj = {};
	- 字面量可以在创建对象时直接向对象中添加属性
	- var obj = {name:"孙悟空",age=18};  // 不同属性之间逗号隔开,最后一个属性后不要写逗号

函数 (function)

函数也是一个对象和其他的对象功能一样
不同的是在函数中可以直接存储JS代码
并且可以在我们需要的时候对这些代码进行反复的调用

2.1 声明函数

创建函数:
	function 函数名(){
		语句...
	}

function fn(){   // fn 函数的名字,起名规范也要遵循
	console.log('声明函数');
}


函数调用:
fn();   // 函数对象名 + ()  调用函数  

2.2 匿名函数

函数表达式:  (匿名函数)
	var 变量 = function(){
	语句...
};

	var a = function(){
	console.log('匿名函数');
};
函数调用:
a();

2.3 立即执行函数

会在函数创建后立即调用,并且只会调用一次

//JS 禁止一个以function开头的函数没有名字
/*function(){
		当这样写时会报错误
}*/

所以给函数加一个括号:
(function(){console.log("我是一个匿名函数")});

调用:
1.(function(){console.log("我是一个匿名函数")})(); // 直接尾部括号调用
2.(function(){console.log("我是一个匿名函数")}()); // 括号里面调用

2.4 参数(形参、实参)

形参(形式参数):
//定义函数时,可以在函数的()中指定数量不等的形参
//定义形参就相当于在函数中声明了两个变量,但没有赋值 
function sum(a,b){
	console.log("a=",a,"b=",b);  //见下图1
}
function sum(){
	console.log("a=",a,"b=",b);  //见下图2
}

实参(实际参数):
//在调用函数时,可以在函数的()中传递数量不等的实参
//实参将会赋值给对应的形参
sum(1,2);  // 见下图3
sum("hello","abc");   // 见下图4

//在JS中不会检查实参的类型和数量,可以传递任意类型的实参
//不同类型:
sum(true,false);     //   1+0  =  1
sum(123,'456');      //   字符串拼接  123456
sum(null,undefined)  //  NaN
//不同数量:
//实参数量和形参数量相同,则对应赋值
sum(1,2);  // a = 1, b = 2
//实参少于形参,则没有实参的形参默认为undefined
sum(1);   //  a = 1, undefined
//实参多余形参,则多余的实参不会使用
sum(1,2,3,4)   // a = 1, b = 2

在这里插入图片描述

2.5 函数的返回值

返回值:
	返回值就是函数的执行结果
	通过 return 来设置函数的返回值
语法:
	return;

function sum(a,b){
	return 123;
}

//调用函数时,返回值就是函数的执行结果,可以定义一个变量来接受结果
var a = sum(123,456);   // 把 sum 的返回值赋值给了 a
console.log(a);         //  123

//任何值都可以作为函数的返回值
function fn(){
	return {};
	return {name:"孙悟空"};
	return function(){
		console.log("内部函数")
	}
	return  数字、字符串、布尔值...
}

// 如果不设置return或者return 不跟任何值,则相当于return一个undefined
function fn(){
	//什么也没有写
}

var result = fn();
console.log(result);    // undefined

//return 之后所有的代码都不会执行,return之后函数结束。
function fn(){
	return;
	console.log("return之后的代码");  // 这个并不会在控制台输出显示
}

var result = fn();
console.log(result);    // undefined

2.6 方法

//任何值都可以成为对象的属性,函数也不例外
//如果一个对象的属性是函数
	 //则我们称这个函数是这个对象的方法(method)

var obj = {
	test:function(){
		alert("我是obj中的函数");
	}
}

obj.test()  //  调用了obj的test方法

2.7 作用域

作用域:
	- 作用域指的就是变量的作用范围
	- 作用域分两大类
		1.全局作用域
		2.局部作用域
			- 块作用域
			- 函数作用域 	

2.7.1 全局作用域

全局作用域在页面加载时创建,页面关闭时销毁。
所有直接写在script标签中的内容,都位于全局作用域中。
全局作用域中定义的变量是全局变量,定义的函数是全局函数。可以在任意位置被访问到。
全局作用域中存在一个全局对象 : window , window对象代表浏览器窗口

<script>
let a = 10;       //全局变量
let b = 20;       //全局变量
function fn(){    // 全局函数
	coonsole.log(a);
	coonsole.log(b);
}

fn();
</script>

在这里插入图片描述
在全局作用域中,所有使用 var 声明的变量都会作为全局对象的属性保存
使用function声明的函数都会作为window对象方法保存

<script>
var a = 10;   //  这个时候就是window的属性被保存
var b = 20;
let c = 30;  //  let 声明不会存储在window对象里面
function fn(){
	coonsole.log(a);
	coonsole.log(b);
}

console.log(window.a);    // 10  这个其实指的就是  var  声明的  a
console.log(window.c);    // undefined

//直接为一个没有声明的变量赋值,实际就相当于直接向window对象中添加属性
d = 30;    //   window.d = 30  
</script>

2.7.2 函数作用域

函数作用域在函数调用时创建,调用结束时销毁`
函数每次调用都会产生一个新的函数作用域,每个作用域之间都是相互独立的

//在函数作用域中声明的变量是局部变量,只能在函数内部访问,外部无法访问
function fn(){
	let a = 10;
	var b = 20;     //  var 和 let 在局部声明中其实没有什么区别,外部都不能访问
	//在函数中声明变量不使用声明,则变量会成为一个全局变量(注意!!!)
	c = 30;
	console.log(a,b);
}

fn();   //调用函数则打印 a 和 b 的值 = 10  20

// 在函数外面访问函数内部的变量
console.log(a,b);  // 报错  a is not defined
//得到函数中 c 的值
console.log(c);    // 30

2.7.3 作用域链

//  函数作用域
let a = 10;
function fn(){
	console.log(a);  // 访问外部的 a ,得到值
}

fn();  //  10

// 作用域链
let a = 10;
function fn(){
	let a = 20;
	//当我们访问一个变量时,JS 会先在当前作用域中寻找,在函数作用域中有 a ,所以输出函数作用域的 a 的值,如果没有则去当前作用域的上一层去寻找,以此类推到全局作用域,没有则报错 xxx is not defined
	console.log(a);
}

fn();  //  20

函数定义在哪里,它的上一层作用域就在哪里

let b = 22;
function fn2(){      //  定义位置
	console.log("b=", b);  //b = 22
	// JS中的作用域叫做 词法作用域,函数作用域由它定义的位置来决定的,和调用位置无关
}

function fn3(){
	let b = 33;
	//虽然在 fn3 函数作用域中调用,对于 fn2 来说,fn2 的作用域上一层依然是全局作用域,因为 fn2 定义位置在全局作用域中
	fn2();          //  调用位置 

}

fn3();   

2.8 变量的提升

a = 10;
console.log(a);   //  10

此时 a 的值是 10,

console.log(a);   //  错误: a is not defined
a = 10;

a is not defined 使用了没有声明的变量报的错误,这个时候给这个变量声明

//  var a;    相当于在打印前已经声明了一个a
console.log(a);   //  undefined
var a = 10;

在 JS 中,使用 var 声明的变量会在所有的代码执行前被创建,相当于在打印 a 之前已经先声明了 a,结果是undefined的原因是因为赋值还没有执行。这个特点称为变量的提升。

函数也是一样的,也会被提升

fn();

//声明函数
function fn(){
	console.log("函数1");
}
// 这个时候就会打印输出   : 函数1


fn2();  // fn2 is not function


//函数表达式
var fn2 = function(){ 
	console.log("函数2");
} 

fn2();  //  函数2

var 在 function 的前面,提升的是 var 声明的 fn2 , 所以在前面调用 fn2 这个函数时,会报错。
而在这个函数之后调用,那么因为已经给 fn2 进行了赋值,所以输出函数2。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值