内容:
arguments
函数案例
作用域
作用域链
预解析
js对象
问题:
1.1 arguments有何作用?应用场景?
1.2 函数中可以调用其他函数么?函数返回值可以作为其他函数的参数么?
2 什么是作用域?js有哪几种作用域?作用域有什么作用?
3 什么是作用域链?
4 什么是预解析?什么是变量提升及函数提升?
5 js对象有什么作用?
6 js如何创建对象?
7 如何访问对象中的数据?如何修改对象对象中数据?如何给对象添加数据?
8 什么是构造函数?和对象有什么关系?
9 构造函数中的this指什么?
10 new 起什么作用?
11 如何遍历对象?
arguments
// arguments存放用户传入函数的所有实参,它是内置对象,不需要声明直接使用(只能在函数内部使用)
// arguments是伪数组,可按遍历数组的方式遍历里面的每个元素
function test(){
console.log(arguments)
for(var i=0;i<arguments.length;i++){
console.log(arguments[i])
}
}
test(1,2,3) // Arguments[1,2,3] 1 2 3
// 封装函数,求任意个数中的最大值及最小值
function getMinMax(){
var min=arguments[0],max=arguments[0];
for(var i=1;i<arguments.length;i++){
if(min>arguments[i]){
min = arguments[i]
}
if(max<arguments[i]){
max = arguments[i]
}
}
return [min,max];
}
getMinMax(2,3,4,1)
声明函数的另一种方式
// 声明
var fn = function(形参列表){
函数体
}
// 调用
fn(实参列表)
说明:用这种方式声明的函数,调用语句必须在声明语句的后面,而传统方式声明的函数,可在声明语句之前调用
如:
fn1();//fn1
function fn1(){
console.log('fn1')
}
fn1()//fn1
//fn2()//会报错
var fn2 = function(){
console.log('fn2')
}
fn2()//fn2
函数案例
//封装翻转数组
function reverse(arr) {
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr = [1, 3, 4, 6, 9];
var arr1 = reverse(arr);
console.log(arr1);
var arr2 = reverse(['red', 'pink', 'blue']);
console.log(arr2);
//封装冒泡排序
function sort(arr) {
for (var i = 1; i < arr.length; i++) {
for (var j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
var arr1 = sort([1, 4, 2, 9]);
console.log(arr1);
//封装函数获取某个年份2月份的天数
function backDay() {
var year = prompt('请您输入年份:');
if (isRunYear(year)) { // 调用函数需要加小括号
alert('当前年份是闰年2月份有29天');
} else {
alert('当前年份是平年2月份有28天');
}
}
backDay();
// 判断是否为闰年的函数
function isRunYear(year) {
return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
}
作用域
- 作用域指代码名字(变量名或函数名)的有效范围
- js作用域分全局作用域(script标签范围内)及局部作用域(函数体范围),作用域可减少命名冲突
- 定义在全局作用域中的变量或在函数体中直接赋值未用var声明的变量(强烈不建议使用) 为全局变量,全局有效
- 定义在函数体中的变量及函数形参变量 为 局部变量,只在函数体范围有效
- 局部变量在函数调用结束后即被销毁,比较节省内存,而全局变量在页面开启期间一直有效,更占内存
作用域链
获取函数内部的变量值时,遵循由内而外,链式查找,取最近同名变量的值 的原则
预解析
js代码逐行执行之前,首先会被预解析,包含变量预解析(变量提升)及函数预解析(函数提升)
console.log(num); //undefined
var num=5;
//此处会发生变量提升,变量提升只提升var 变量名,而不提升变量赋值,故以上代码经预解析后相当于如下代码
var num;
console.log(num)
num=5
------------------------------------
test() //弹出 'test'
function test(){
alert('test')
}
//此处发生函数提升,会将function 函数名(){}整体提升到当前作用域的最前面,故以上代码相当于
function test(){
alert('test')
}
test()
------------------------------------
fun() //报错
var fun = function(){alert('fun')}
//此处发生变量提升,会将var fun提升到当前作用域的最前面,以上代码相当于
var fun;
fun();//此时fun为undefined
fun=function(){alert('fun')}
js对象
对象概念
计算机程序最初主要用于大型数学运算,故主要采用面向过程的编程方式(专注于解决问题的步骤)。后面被广泛用于生活的方方面面,故程序需要能描述现实世界更多的事物,由此出现面向对象编程。
世间万物皆可抽象为对象(一组特性及行为的集合)。
js对象为一组属性的集合,格式为{属性名1:属性值1,属性名2:属性值2,...,属性名n:属性值n},当属性值为函数时,则该属性又被称为方法。
对象的创建及使用
//创建对象-方法1:字面量方式
var obj = {属性名1:属性值1,属性名2:属性值2,...,属性名n:属性值n}
//当属性值为一个函数时,则该属性又被称为方法
var obj = {
name:'zhangsan',
age:20,
sing:function(){alert('哈哈哈')}}
//通过 对象名.属性名 或对象['属性名'] 来访问对象的属性值 ,通过对象名.方法名()或对象['方法名']()来使用对象方法 如:
console.log(obj.name);
console.log(obj['name']);
obj.sing()
obj['sing']()
//js对象可以动态新增属性
obj.sex='male';
var test = {name:'zhangsan',age:20,name:'lisi'}
console.log(test)// {name:'lisi',age:20} 对象中不允许出现重复属性名,重复时后面的会覆盖前面的
创建对象的其他方式
//方法2:new Object()方式-较繁琐,实际使用较少
var obj = new Object() // 等效于 var obj = {}
//往空对象中动态添加属性
obj.name = '张三';
obj.age = 19;
obj.sex = 'male';
obj.tech = function(){
alert('隐身')
}
console.log(obj.name);
obj.tech();
// 方法3:工厂函数-了解
function star(name, age, song) {
var o = {};
o.uname = name;
o.age = age;
o.sing = function () {
console.log(song);
};
return o;
}
var zjl = star('周杰伦', 40, '七里香');
var gfc = star('郭富城', 58, '爱不完');
console.log(zjl, gfc);//得到的对象 不会留下任何star的痕迹
zjl.sing();
gfc.sing();
// 方法4:构造函数-重点 需要创建多个具备相同属性对象时可先封装构造函数
function Star(name, age, song) {
// 构造函数函数名 首字母大写
this.uname = name; //此处this指即将构造出来的对象
this.age = age;
this.sing = function () {
console.log(song);
};
}
var lm = new Star('黎明', 60, '一万年');
var wf = new Star('汪峰', 50, '怒放的生命');
console.log(lm, wf);//通过构造函数得到的对象会留下构造函数的标记
lm.sing();
wf.sing();
var test = Star('黎明', 60, '一万年'); //使用构造函数创建对象时必须用new
console.log(test); // undefined
构造函数和对象的关系
构造函数在js(ES5)中相当于其他面向对象编程语言(java/c++)中的类,对象为类的实例,类为对对象公共特性的抽象。由构造函数创建对象的过程又被称为实例化
new 的作用
在构造函数创建对象的过程中,new起关键作用,new主要做了如下事情:
1 创建空对象并让this指向该空对象
2 执行构造函数,给上述空对象增加属性
3 返回已经增加了属性的对象
任何函数都可以是构造函数,函数是不是构造函数由new决定
对象的遍历
// js对象通过 for...in...结构遍历
var obj = {name:'jim',age:20,sex:'男'}
for(var k in obj){
console.log(k) //会输出3次 name age sex
console.log(obj[k]) // jim 20 男
}
// in可判断对象中是否存在某个属性 如:
'name' in obj // true
'sayHi' in obj // false