目录
- 函数
- 定义方式一
- 定义方式二
- 调用函数
- 函数中的参数传递
- arguments
- rest
- 变量的作用域
- 函数作用域
- 全局函数
- 全局对象 window
- 规范
- 局部作用域 let
- 常量 const
- 方法
- apply(控制 this 指向)
函数
定义方式一
这里以绝对值函数为例
<script>
function abc(x) {
if(x>=0) {
return x;
}else {
return -x;
}
}
</script>
一旦执行到 return 代表函数结束,返回结果
如果没有执行 return,函数执行完也会返回结果,结果就是undefined
定义方式二
相当于匿名函数,把结果赋给了abc,通过abc来调用
<script>
var abc = function(x) {
if(x>=0) {
return x;
}else {
return -x;
}
}
</script>
调用函数
abc(10);
abc(-3);
参数问题:javaScript 可以传任意个参数,也可以不传递参数
参数进来是否存在的问题? 不存在,怎么办
<script>
var abc = function(x) {
if(typeof x != 'number') {
throw 'Not a Number';
}
if(x>=0) {
return x;
}else {
return -x;
}
}
</script>
函数中的参数传递
arguments
arguments 是js免费赠送的关键字
- 代表,传递进来的所有参数,是一个数组
<script>
var abc = function(x) {
for(var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
if(x>=0) {
return x;
}else {
return -x;
}
}
</script>
问题:arguments 包含所有的参数,我们有时候想使用多余的参数进行附加操作,需要排出已有的参数
rest
ES6引入的新特性,获取除了已经定义的参数之外的所有参数
- rest 参数只能写在最后面,必须用…标识
<script>
function aaa(a,b, ...rest) {
//获取除a、b之外传入的所有函数,返回一个数组
console.log(rest);
}
</script>
变量的作用域
函数作用域
在javascript中,var定义变量实际是有作用域的
- 假设在函数体中声明,则在函数体外不可使用~ (闭包)
<script>
function a() {
var x = 2;
x = x + 2;
}
//x is not defined
x = x + 3;
</script>
- 如果两个函数使用了相同的变量名,只要在函数内部,就不冲突
<script>
function a() {
var x = 2;
x = x + 2;
}
function b() {
var x = 2;
x = x + 2;
}
</script>
- 内部函数可以访问外部函数的成员,反之则不行
<script>
function f() {
var x = 2;
// 内部函数可以访问外部函数的成员,反之则不行
function f1() {
//y is not defined
var y = x + 3;
}
// y is not defined
var z = y +2;
}
</script>
- 外部函数与内部函数变量名相同时,内部函数会屏蔽外部函数变量
<script>
function a() {
var x = 2;
function b() {
var x = 'A';
console.log('inner'+x);
}
b();
console.log('outer'+x);
}
</script>
- 提升变量的作用域
<script>
function a() {
var x = 'x'+y;
console.log(x);
var y = 'y';
console.log(y);
}
//等价于
// function a() {
// var y;
// var x = 'x'+y;
// console.log(x);
// y = 'y';
// console.log(y);
// }
</script>
结果:xundefined
说明:js执行引擎,自动提升了y的声明,但是不会提升变量y的赋值
全局函数
<script>
//全局函数
var x = 2;
function a() {
console.log(x);
}
a();
console.log(x);
</script>
全局对象 window
-
默认所有的全局遍历,都会自动绑定在 window对象下
-
alert() 这个函数本身也是一个 window 变量
-
js实际上只有一个全局作用域,任何变量(函数也可以视为变量) ,范围内没找到,就会向外找,如果在全局作用域都没有找到,报 RefrenceError
引用错误
<script>
var x = 'xxx';
alert(x);
alert(window.x); //默认所有的全局遍历,都会自动绑定在 window对象下
</script>
<script>
var x = 'aaa';
// var oldAlert = window.alert(x);
window.alert = function () {
}
//发现 alert()失效了
window.alert("bbb");
//恢复
// window.alert = oldAlert;
// window.alert("ccc");
</script>
规范
- 由于全部变量都绑定在window上,如果不同js文件,使用相同的全局遍历,就会产生冲突
- 把自己的代码放入自己定义的唯一全局变量中,降低全局变量名的冲突
- jQuery就是用的该办法 jQuery.xxx 与 $.xxx 时一样的
<script>
//唯一全局变量
var js = {};
//定义全局变量
js.name = 'klz';
//定义全局方法
js.age = function (a,b) {
return a+b;
}
console.log(js.name);
console.log( js.age(1,5))
</script>
局部作用域 let
- let 是 ES6 关键字,解决局部作用域的冲突问题
原来的写法值为101
<script>
function f() {
for(var i = 0; i < 100; i++) {
console.log(i);
}
//值为101 i 出了作用域还可以用
console.log(i+1);
}
</script>
ES6 用 let 结果为100
<script>
function f() {
for(let i = 0; i < 100; i++) {
console.log(i);
}
//值为100 i 出了作用域没效果了
console.log(i+1);
}
</script>
常量 const
- 在ES6 之前,定义常量: 只有用全部大写字母,不建议修改值
- ES6 引入了常量关键字
<script>
var PI = 3.14;
console.log(PI);
PI = '213';
console.log(PI);
</script>
使用了 const 的话,要修改会报红
<script>
const PI = 3.14;
console.log(PI);
PI = '213';
console.log(PI);
</script>
方法
- js中,方法就是函数放在对象里面,对象只有: 属性和方法
<script>
var info = {
name: 'klz',
brith: 1998,
//方法
age: function () {
// 今年 - 出生的年
var nowYear = new Date().getFullYear();
return nowYear - this.brith;
}
}
//输入属性
info.name
//输入方法
info.age()
</script>
- this 代表什么
- 控制台输入info.age() 值为22(this是对象里面的)
- 控制台输入getAge() 报NaN(window里面没有 this)
- this 是无法指向的,是默认指向调用它的哪个对象
拆分上面的代码
<script>
function getAge() {
// 今年 - 出生的年
var nowYear = new Date().getFullYear();
return nowYear - this.brith;
}
var info = {
name: 'klz',
brith: 1998,
//方法
age: getAge
}
</script>
apply(控制 this 指向)
- 在 js 中可以控制 this 指向
- getAge.apply(info,[]); --> this 指向 info 对象, 参数为空
<script>
function getAge() {
// 今年 - 出生的年
var nowYear = new Date().getFullYear();
return nowYear - this.brith;
}
var info = {
name: 'klz',
brith: 1998,
//方法
age: getAge
}
//在控制台输入 this 指向 info 对象, 参数为空
getAge.apply(info,[]);
</script>