JavaScript03:函数和方法
函数和方法是一样的,只是对于对象来说,函数被绑定在对象上,称为这个对象的方法
JavaScript的函数也被看作是对象,可以被赋值,可以传任意个参数不报错,参数少了返回undefined或NaN,参数多了忽略
函数定义和参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的网页</title>
<script>
"use strict";
/**
* 函数定义方式一:function 函数名(){}
*/
function abs1(x){
if (x < 0){
return -x;
}
return x;
}
/**
* 函数定义方式二:let 函数名 = function(){}
* 函数也是对象,可以赋值给变量
*/
let abs2 = function (x){
if (x < 0){
return -x;
}
return x;
}
/**
* alert()方法可以被赋值失效
*/
alert = function(){};
alert("Hello");
/**
* 如果调用时没有参数,手动抛出异常
*/
function test1(x){
if (typeof x !== "number"){
throw "Not a number"
}
}
/**
* 如果调用时传入参数多了,后面的会忽略,但是可以用arguments关键字数组获取到
* arguments数组记录了所有传进的参数,包括未定义的多余参数,且只能用for循环遍历出未定义的参数
*/
function test2(x){
if (arguments.length > 1){
for (let i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
else {
return x;
}
}
/**
* rest可变长参数数组,可以单独获得未定义的传参值
*/
function test3(x, ...rest){
console.log(x);
console.log(rest);
}
</script>
</head>
<body>
</body>
</html>
变量作用域
变量如果不用var或者let定义,会自动被声明为全局变量,很不安全,因此要使用strict模式,强制用let或var定义
var是函数作用域,变量只在函数内是有效的,先使用后声明也行,但值是undefined,可以被重新定义。在for循环定义一个var变量,在for循环外也可以访问
let是块作用域,变量只在块中有效,必须先声明再使用。在for循环定义一个let变量,在for循环外是不可被访问的,所以for循环推荐用let
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的网页</title>
<script>
"use strict";
function test1(){
var x = "x" + y;
console.log(x);
var y = "y";
}
function test2(){
let x = "x" + y;
console.log(x);
let y = "y";
}
/**
* var定义变量,如果先使用后定义,会自动提升变量作用域(值为undefined),不会报错
* 而let未定义使用会报错
* 因此建议所有变量定义都放在头部
*/
test1();
test2();
</script>
</head>
<body>
</body>
</html>
全局变量和常量
不在任何函数内定义的变量就是全局变量,而所有全局变量都被绑定为全局对象window的属性,如alert()方法,定义的全局变量等
可以通过默认的window对象调用所有全局变量,每个文件可以自定义一个全局对象,间接创建调用其他变量,避免和其他文件冲突
const关键字定义常量,全部大写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的网页</title>
<script>
"use strict";
/**
* 任何全局变量都是window对象的属性,可以直接调用
*/
window.alert("Hello");
/**
* 自定义一个全局对象,又称命名空间,间接创建调用其他变量
*/
let MyName = {};
MyName.name = "ty";
console.log(MyName.name);
/**
* const关键字定义常量
*/
const PI = "3.14";
console.log(PI);
</script>
</head>
<body>
</body>
</html>
方法
方法就是把函数放在对象的内部,对象只有属性和方法
apply()/call()方法可以让this指定对象,方便多个对象调用同一个方法,不同点是apply()方法传入参数列表,call()一个个传入参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>我的网页</title>
<script>
"use strict";
let xiaoming = {
/**
* 属性
*/
name: "xiaoming",
birth: 1990,
/**
* 方法
* 定义方式一
*/
age: function (){
let now = new Date().getFullYear();
return now - this.birth;
},
/**
* 定义方式二
* 将方法具体内容写在外面,只引用方法名
*/
address: name
}
function name (){
return this.name;
}
let xiaohong = {
name: "xiaohong",
address: name
}
console.log(xiaoming.age());
console.log(xiaoming.address());
/**
* 方式二中不能直接调用这个name()方法,因为默认是用window对象来调用,而window没有name这个属性
* 可以通过apply()/call()方法来指定this指向的对象(分别传入要指向的对象,还有参数),方便多个对象调用同一个方法
*/
console.log(name);
console.log(name.apply(xiaoming, []));
console.log(name.call(xiaohong, ));
</script>
</head>
<body>
</body>
</html>