函数
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> /* * 创建函数的方式一: * - 使用函数声明来创建一个函数 * - 语法: * function 函数的名字([形参1,形参2,...形参n]){ * 语句... * } */ //创建一个函数 function fun(){ console.log("语句一"); console.log("语句二"); console.log("语句三"); } //调用函数 fun(); /* * 创建函数的方式二: * - 使用函数表达式来创建一个函数 * - 语法: * var 变量 = function([形参1,形参2,...形参n]){ * 语句... * }; */ var fun2 = function(){ alert("我是又一个函数"); }; //调用函数 fun2(); </script> </head> <body> </body> </html>
js中函数可以作为参数传递
第一种写法
function say (value) { alert(value); } function execute (someFunction, value) { someFunction(value);//回调函数 } execute(say, 'hi js.');
上面代码是将say方法作为参数传递给execute方法
第二种写法
var say = function(value) { alert(value); } function execute (someFunction, value) { someFunction(value);//回调函数 } execute(say, 'hi js.');
第三种写法
function execute (someFunction, value) { someFunction(value);//回调函数 } execute(function(value) { alert(value); }, 'hi js.');
上述代码中execute方法的第一个参数是一个匿名函数。
何谓匿名函数
没有函数名的函数
1 分析: 函数为何要有名字? 是为了方便下次使用.
2 用途: 通常不希望再次使用(即只使用一次的)的函数可以定义为匿名函数.
上面的函数say被叫做回调函数
回调函数
就是你调用别人(execute),然后别人会调用你(say),简言之:你写一个函数(say),但不是由你调用,是由你调用的一个函数(execute)调用。
函数做为返回值
function fn2(a){ return function (b){ alert(a+b); }; } fn2(20)(10);//30
arguments
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> /* *在调用函数时,浏览器还传递了另一个隐含的参数 * 还有一个参数叫做arguments * * arguments是一个类数组对象,在它里边保存着函数执行时的实参 * 函数的所有的实参都在arguments中保存, * 通过arguments即使不定义形参也可以使用参数 * * */ function fun(a,b,c){ //获取实参的数量 //console.log(arguments.length); //获取指定的实参 //实参会保存到arguments对象中指定的位置 //console.log(arguments[2]); } fun("hello",123,true); </script> </head> <body> </body> </html>
变量作用域
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> /* * 作用域(Scope) * - 作用域简单来说就是指一个变量的作用的范围 * - 在JS中作用域分成两种: * 1.全局作用域 * 2.函数作用域 * * - 全局作用域: * 1.所有直接在script标签中编写的代码都在全局作用域中 * 2.全局作用域在打开网页时创建,在网页关闭时销毁 * 3.全局作用域中有一个全局对象window, * window代表的是浏览器的窗口, * 在全局作用域中创建的变量都会作为window对象的属性保存 * 在全局作用域中创建的函数都会作为window对象的方法保存 * 4.在全局作用域中创建的变量都是全局变量,可以在页面的任意位置访问 */ var a = 123; b = 456; function fun(){ console.log(b); console.log(window.a); console.log(window.b); console.log("我是全局中的函数fun。。。。"); } fun(); //window.fun(); //window.alert("hello"); </script> </head> <body> </body> </html>
变量和函数的声明提前:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> //如果不写var,直接为变量赋值,则相当于为window对象添加属性 //window.a = 10; //a = 10; /* * 变量的声明提前 * - 使用var关键字声明的变量,都会在所有的代码执行之前被声明,但是不会赋值 * 赋值会直到执行到赋值的代码时才执行 * - 如果不适用var关键字声明变量,则不会有声明提前的特性 * * 函数的声明提前 * - 使用函数声明创建的函数,会在所有的代码执行之前创建, * 所以我们可以在函数声明前就去调用函数 * - 使用函数表达式创建的函数,没有这个特性,所以不能在它创建之前调用 */ console.log("a = "+a); var a = 10; //fun(); fun2(); //使用函数声明来创建一个函数 function fun(){ console.log("我是fun函数。。。。"); } //使用函数表达式创建一个函数 var fun2 = function(){ console.log("----->我是fun2.。。。"); }; </script> </head> <body> </body> </html>
函数作用域
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> /* * 函数作用域 * - 函数作用域可以理解为是全局中的小的作用域 * - 函数作用域在函数调用时创建,在调用结束时销毁 * 每调用一次函数就会创建一个新的函数作用域 * - 在函数作用域中可以访问到全局变量, * 而在全局中无法访问到函数作用域中的变量 * 在函数中创建的变量如果不写var,则会变成全局变量 * - 当我们在函数中使用一个变量时,它会先在自身的作用域中寻找, * 如果有就直接使用,如果没有则去上一级作用域中寻找, * 找到则使用,没找到则继续寻找,直到找到全局作用域为止 * 如果全局作用域中依然没有,则报错ReferenceError * - 在函数作用域中也适用变量和函数的声明提前 * */ //创建一个全局变量a var a = "全局中的a"; function fun(){ //console.log(a); //window.b = ... var b = "---> 函数作用域中的b"; //console.log(b); } //fun(); //console.log(b); //创建全局变量c var c = "全局c"; console.log(window.c); /*function fun2(){ //创建一个局部变量c var c = "---> 函数中的c"; console.log(c); } fun2();*/ function fun3(){ //var c = "fun3中的c"; function fun4(){ //var c = "fun4中的c"; console.log(c); } //调用fun4 fun4(); } //fun3(); </script> </head> <body> </body> </html>
例子2
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> var a = "全局a"; function fun(){ var a = "--> 函数a"; //如果在函数作用域中想访问全局变量可以通过window对象来访问 console.log(window.a); } //fun(); a = 20; /* * 在函数内部使用var关键字声明的变量也会被声明提前, * 它的声明会在所有的代码执行前执行 * * 在函数内部使用函数声明创建的函数,也会在所有的代码执行之前被创建 */ function fun2(){ fun3(); //console.log(a); //var a = 10; function fun3(){ console.log("我是fun2内部的函数。。。"); } } fun2(); </script> </head> <body> </body> </html>
另一个例子
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> // var a = 10; // // function fun(){ // // a = 5; // // } // // fun(); // // console.log(a);//10 ---函数作用域在函数调用时创建,在调用结束时销毁 var a = 123; /* * 定义形参就相当于在函数中声明了对应的变量 */ function fun(a) { alert(a); a = 456; } fun(); //undefined alert(a); //123 var a = 123; function fun(a) { alert(a); a = 456; } fun(123); //123 alert(a); //123 </script> </head> <body> </body> </html>
类的定义
//class关键字必须是小写。 后面就是跟的类名 class PersonClass { // 等效于 PersonType 构造函数。 constructor(name) { //这个表示类的构造函数。constuctor也是关键字必须小写。 this.name = name; //创建属性。 也叫当前类型的自有属性。 } sayName() { console.log(this.name); } } var person = new PersonClass("Nicholas"); person.sayName(); // 输出 "Nicholas"
继承
class Father{ constructor(name){ this.name = name; } sayName(){ console.log(this.name); } } class Son extends Father{ //extents后面跟表示要继承的类型 constructor(name, age){ super(name); this.age = age; } //子类独有的方法 sayAge(){ console.log(this.age); } } var son1 = new Son("李四", 30); son1.sayAge(); son1.sayName();
子类重写父类的方法
class Father{ constructor(name){ this.name = name; } sayName(){ console.log(this.name); } } class Son extends Father{ //extents后面跟表示要继承的类型 constructor(name, age){ super(name); //相当于以前的:Father.call(this, name); this.age = age; } //子类独有的方法 sayAge(){ console.log(this.age); } //子类中的方法会屏蔽到父类中的同名方法。 sayName(){ super.sayName(); //调用被覆盖的父类中的方法。 console.log("我是子类的方法,我屏蔽了父类:" + name); } } var son1 = new Son("李四", 30); son1.sayAge(); son1.sayName();