函数
定义和调用
系统函数:
- parseInt():是将字符串转换为整数。
- parseFloat():是结果返回一个浮点数。
- isNan():判断函数是否是NaN(是不是数字),是数字返回false,反之true。
- eval():是以字符串形式表示js代码串,并回馈执行的结果。
自定义函数
function 函数名(){
语句
}
还有就是匿名函数 自己调自己
<script type="text/javascript">
(function(a, b) {
var c = a * b;
console.log(c)
})(2, 50);
</script>
可以当变量用,也可以当方法用
<script type="text/javascript">
var demo = (function(a, b) {
var c = a * b;
console.log(c);
});
demo(2, 50); //当方法使用
console.log(demo); //当变量输出
</script>
调用
//作为函数调用
<script type="text/javascript">
function f1(a, b) {
console.log(this) //window
return a * b;
}
var sum = f1(3, 4); // 12
console.log(sum)
</script>
//作为方法调用
<script type="text/javascript">
var f1 = {
name: "zhangsan",
age: 23,
f2: function() {
console.log(this) //{name: "zhangsan", age: 23, f2: ƒ}
return this.name + " " + this.age;
return this;
}
}
f1.f2(); // zhangsan 23
</script>
//使用构造函数调用
<script type="text/javascript">
function f1(arg1, arg2) {
this.name = arg1;
this.age = arg2;
}
var x = new f1("zhangsan", 23);
x.name; //返回 zhangsna
console.log(x.name)
</script>
//作为函数方法调用
<script type="text/javascript">
var fun;
function f1(a,b){
return a*b;
}
fun=f1.call(fun , 3 , 4); //返回 12
console.log(fun)
</script>
<script type="text/javascript">
function f1(a,b){
return a*b;
}
var f2=[3,4];
var f3=f1.apply(f3,f2) //返回12
console.log(f3)
</script>
this
函数内部的this指向
在不使用call、apply、bind的情况下,这些this的指向,当我们调用函数的时候是确定的。调用函数的不同决定了this指向的不同
| 调用方式 | this指向 |
|---|---|
| 普通函数 | 严格模式下是undefined,正常模式是Window |
| 表达式函数 | 严格模式下是undefined,正常模式是Window |
| 构造函数 | 实例对象 |
| 对象方法调用 | 该方法所属的对象 |
| 事件绑定方法 | 当前事件所绑定的对象 |
| 定时器函数 | Window |
| 立即执行函数(自调用函数) | 严格模式下是undefined,正常模式是Window |
普通函数
正常模式:this指向Window
<script type="text/javascript">
function fn () {
console.log(this) //Window {window: Window, self: Window, document: document, name: "", location: Location, …}
}
fn();
</script>
严格模式:this不知道指向谁,所以打印undefined
<script type="text/javascript">
function fn () {
'use strict'
console.log(this) //undefined
}
fn();
</script>
表达式函数
严格模式下this是undefined,正常模式是Window
<script type="text/javascript">
var fn = function() {
console.log(this) //Window {window: Window, self: Window, document: document, name: "", location: Location, …}
}
fn();
</script>
构造函数
构造函数的this指向实例对象,下例指向实例对象fn
<script type="text/javascript">
function fn(name) {
this.name=name;
console.log(this) //fn {name: "constructor function"}
}
var fn = new fn('constructor function');
</script>
对象方法调用
对象调用自身方法时的this指向该方法所属的对象
<script type="text/javascript">
var obj = {
name:'zhangsan',
say:function() {
console.log(this)
}
}
obj.say() //obj {name: "zhangsan", say: ƒ}
</script>
事件绑定方法
事件绑定时,this指向当前事件所绑定的对象
<button>点我</button>
<script type="text/javascript">
var btn = document.querySelector('button');
btn.onclick = function() {
console.log(this) //button按钮
}
</script>
定时器函数
定时器里的函数是回调函数,所有回调函数的this都指向Window
<script type="text/javascript">
setTimeout(function() {
console.log(this) //Window {window: Window, self: Window, document: document, name: "", location: Location, …}
}, 1000)
</script>
立即执行函数(自调用函数)
严格模式下this是undefined,正常模式是Window
<script type="text/javascript">
(function(){
'use strict'
console.log(this) //undefined
})()
</script>
改变函数内部的指向
1. call方法
- call()方法调用一个对象
- 简单理解为调用函数的方式,但是它可以改变函数的 this 指向
- 应用场景: 经常做继承
<script type="text/javascript">
var f1 = {
name: 'zhangsan'
}
function fn(a, b) {
console.log(this);
console.log(a+b)
};
fn() // 此时this的指向是window
fn.call(f1,1,2) //此时的this指向的是对象f1,参数使用逗号隔开
// call 第一个可以调用函数 第二个可以改变函数内的this 指向
// call 的主要作用可以实现继承
function Father(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
function Son(name, age, sex) {
Father.call(this, name, age, sex);
}
var son = new Son('张三', 23, '男');
console.log(son);
</script>
2. apply方法
- apply() 方法调用一个函数
- 简单理解为调用函数的方式,但是它可以改变函数的 this 指向
- 应用场景: 经常跟数组有关系
<script type="text/javascript">
var f1 = {
name: 'andy'
}
function fn(a, b) {
console.log(this);
console.log(a+b)
};
fn()// 此时的this指向的是window
fn.apply(f1,[1,2])//此时的this指向的是对象o,参数使用数组传递
// 1. 也是调用函数 第二个可以改变函数内部的this指向
// 2. 但是他的参数必须是数组(伪数组)
// 3. apply 的主要应用 比如说我们可以利用 apply 借助于数学内置对象求数组最大值
// Math.max();
var arr = [1, 66, 3, 99, 4];
var arr1 = ['red', 'pink'];
// var max = Math.max.apply(null, arr);//不需要改变this指向,写null
var max = Math.max.apply(Math, arr);//但是写null不太合适,写max的调用者Math最好,最大
var min = Math.min.apply(Math, arr);//但是写null不太合适,写max的调用者Math最好,最小
console.log(max, min);
</script>
3. bind方法
- bind() 方法不会调用函数,但是能改变函数内部this 指向,返回的是原函数改变this之后产生的新函数
- 如果只是想改变 this 指向,并且不想调用这个函数的时候,可以使用bind
- 应用场景:不调用函数,但是还想改变this指向
<script type="text/javascript">
var f1 = {
name: 'andy'
};
function fn(a, b) {
console.log(this);
console.log(a + b);
};
var f = fn.bind(f1, 1, 2); //此处的f是bind返回的新函数
f(); //调用新函数 this指向的是对象f1 参数使用逗号隔开
</script>
4. call、apply、bind三者异同
- 共同点 : 都可以改变this指向
- 不同点:
- call 和 apply 会调用函数, 并且改变函数内部this指向.
- call 和 apply传递的参数不一样,call传递参数使用逗号隔开,apply使用数组传递
- bind 不会调用函数, 可以改变函数内部this指向.
- 应用场景
- call 经常做继承.
- apply经常跟数组有关系. 比如借助于数学对象实现数组最大值最小值
- bind 不调用函数,但是还想改变this指向. 比如改变定时器内部的this指向
严格模式
ES5的严格模式是采用具有限制性javaScript变体的一种方式,即在严格的条件下运行。IE10以上支持,旧版本会被忽略。 特点:
- 消除了JavaScript语法的一些不合理、不严谨之处
- 消除代码运行中的不安全之处,保证运行安全
- 提高编译器效率,增加运行速度。
- 禁用了在ECMScript的未来版本中可能会定义的一些语法,如一些保留字不能做变量名(class、enum、export、extends、import、super)
- 严格模式可以应用到整个脚本或者个别函数中 为脚本开启严格模式 需要在所有的js语句之前写
'use strict';
//下面的js代码会按照严格模式执行
有的js是基本模式,有些是严格模式的情况,可以将真个脚本文件放在一个立即执行的匿名函数中,这样独立创建一个作用域,不影响其他js脚本文件
<script type="text/javascript">
(function() {
"use stroct";
})()
</script>
为函数开启严格模式 在函数内部第一行写’use strict’;
<script type="text/javascript">
function fun(){
'use strict';
//函数内部下面的代码按照严格模式执行
}
</script>
严格模式的要求
- 正常模式中,如果一个变量没有声名就赋值,默认是全局变量。严格模式禁止这种用法,变量必须先声名,才能使用。
- 严禁删除已经声名的变量。
<script type="text/javascript">
'use strict';
var x = 10;
delete x; //会报错
console.log(x)
</script>
- 严格模式下this 指向问题 普通模式下this指向window对象,严格模式下全局作用域中函数中的this是undefined。 严格模式下,构造函数不加new调用,会报错,加new调用,this指向的还是创建的实例 定时器中的this指向还是window 事件、对象还是指向调用者
- 函数中不能有重名的参数
- 现版本的JavaScript引入“块级作用域”ES6中已经引入,所以严格模式不允许在非函数的代码块中sh声明函数。 如 if {} for(){} 严格模式不允许用8进制
量必须先声名,才能使用。
- 严禁删除已经声名的变量。
<script type="text/javascript">
'use strict';
var x = 10;
delete x; //会报错
console.log(x)
</script>
- 严格模式下this 指向问题 普通模式下this指向window对象,严格模式下全局作用域中函数中的this是undefined。 严格模式下,构造函数不加new调用,会报错,加new调用,this指向的还是创建的实例 定时器中的this指向还是window 事件、对象还是指向调用者
- 函数中不能有重名的参数
- 现版本的JavaScript引入“块级作用域”ES6中已经引入,所以严格模式不允许在非函数的代码块中sh声明函数。 如 if {} for(){} 严格模式不允许用8进制