函數(shù)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
/*
* 創(chuàng)建函數(shù)的方式一:
* - 使用函數(shù)聲明來創(chuàng)建一個函數(shù)
* - 語法:
* function 函數(shù)的名字([形參1,形參2,...形參n]){
* 語句...
* }
*/
//創(chuàng)建一個函數(shù)
function fun(){
console.log("語句一");
console.log("語句二");
console.log("語句三");
}
//調(diào)用函數(shù)
fun();
/*
* 創(chuàng)建函數(shù)的方式二:
* - 使用函數(shù)表達(dá)式來創(chuàng)建一個函數(shù)
* - 語法:
* var 變量 = function([形參1,形參2,...形參n]){
* 語句...
* };
*/
var fun2 = function(){
alert("我是又一個函數(shù)");
};
//調(diào)用函數(shù)
fun2();
</script>
</head>
<body>
</body>
</html>
js中函數(shù)可以作為參數(shù)傳遞
第一種寫法
function say (value) {
alert(value);
}
function execute (someFunction, value) {
someFunction(value);//回調(diào)函數(shù)
}
execute(say, 'hi js.');
上面代碼是將say方法作為參數(shù)傳遞給execute方法
第二種寫法
var say = function(value) {
alert(value);
}
function execute (someFunction, value) {
someFunction(value);//回調(diào)函數(shù)
}
execute(say, 'hi js.');
第三種寫法
function execute (someFunction, value) {
someFunction(value);//回調(diào)函數(shù)
}
execute(function(value) {
alert(value);
}, 'hi js.');
上述代碼中execute方法的第一個參數(shù)是一個匿名函數(shù)。
何謂匿名函數(shù)
沒有函數(shù)名的函數(shù)
1 分析: 函數(shù)為何要有名字? 是為了方便下次使用.
2 用途: 通常不希望再次使用(即只使用一次的)的函數(shù)可以定義為匿名函數(shù).
上面的函數(shù)say被叫做回調(diào)函數(shù)
回調(diào)函數(shù)
就是你調(diào)用別人(execute),然后別人會調(diào)用你(say),簡言之:你寫一個函數(shù)(say),但不是由你調(diào)用,是由你調(diào)用的一個函數(shù)(execute)調(diào)用。
function myfilter(func) {
var return_arr = [];
var arr = ["豬八戒","豬八戒","沙和尚","唐僧","孫悟空","白骨精","白骨精","唐僧","白骨精"];
for(var i = 0; i < arr.length; i++)
{
var result = func(arr[i],i,arr);
if(result== true)
{
return_arr.push(arr[i]);
}
}
return return_arr;
}
var newarr = myfilter(function (value,index,obj) {
if(obj.indexOf(value,index+1) == -1)//后面沒有和我一樣的元素了
{
return true;
}
else//后面還有和我一樣的元素,我先不加入到最終數(shù)組newarr中
{
return false;
}
});
console.log(newarr);
函數(shù)做為返回值
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">
/*
*在調(diào)用函數(shù)時,瀏覽器還傳遞了另一個隱含的參數(shù)
* 還有一個參數(shù)叫做arguments
*
* arguments是一個類數(shù)組對象,在它里邊保存著函數(shù)執(zhí)行時的實參
* 函數(shù)的所有的實參都在arguments中保存,
* 通過arguments即使不定義形參也可以使用參數(shù)
*
*
*/
function fun(a,b,c){
//獲取實參的數(shù)量
//console.log(arguments.length);
//獲取指定的實參
//實參會保存到arguments對象中指定的位置
//console.log(arguments[2]);
}
fun("hello",123,true);
</script>
</head>
<body>
</body>
</html>
變量作用域
作用域(Scope)
* - 作用域簡單來說就是指一個變量的作用的范圍
* - 在JS中作用域分成兩種:
* 1.全局作用域
* 2.函數(shù)作用域
*
* - 全局作用域:
* 1.所有直接在script標(biāo)簽中編寫的代碼都在全局作用域中
* 2.全局作用域在打開網(wǎng)頁時創(chuàng)建,在網(wǎng)頁關(guān)閉時銷毀
* 3.全局作用域中有一個全局對象window,
* window代表的是瀏覽器的窗口,
* 在全局作用域中創(chuàng)建的變量都會作為window對象的屬性保存
* 在全局作用域中創(chuàng)建的函數(shù)都會作為window對象的方法保存
* 4.在全局作用域中創(chuàng)建的變量都是全局變量,可以在頁面的任意位置訪問
*/
var a = 123;
b = 456;
function fun(){
console.log(b);
console.log(window.a);
console.log(window.b);
console.log("我是全局中的函數(shù)fun。。。。");
}
fun();
//window.fun();
//window.alert("hello");
變量和函數(shù)的聲明提前:
//如果不寫var,直接為變量賦值,則相當(dāng)于為window對象添加屬性
//window.a = 10;
//a = 10;
/*
* 變量的聲明提前
* - 使用var關(guān)鍵字聲明的變量,都會在所有的代碼執(zhí)行之前被聲明,但是不會賦值
* 賦值會直到執(zhí)行到賦值的代碼時才執(zhí)行
* - 如果不適用var關(guān)鍵字聲明變量,則不會有聲明提前的特性
*
* 函數(shù)的聲明提前
* - 使用函數(shù)聲明創(chuàng)建的函數(shù),會在所有的代碼執(zhí)行之前創(chuàng)建,
* 所以我們可以在函數(shù)聲明前就去調(diào)用函數(shù)
* - 使用函數(shù)表達(dá)式創(chuàng)建的函數(shù),沒有這個特性,所以不能在它創(chuàng)建之前調(diào)用
console.log("a = "+a);
var a = 10;
//fun();
fun2();
//使用函數(shù)聲明來創(chuàng)建一個函數(shù)
function fun(){
console.log("我是fun函數(shù)。。。。");
}
//使用函數(shù)表達(dá)式創(chuàng)建一個函數(shù)
var fun2 = function(){
console.log("----->我是fun2.。。。");
};
函數(shù)作用域
- 函數(shù)作用域
* - 函數(shù)作用域可以理解為是全局中的小的作用域
* - 函數(shù)作用域在函數(shù)調(diào)用時創(chuàng)建,在調(diào)用結(jié)束時銷毀
* 每調(diào)用一次函數(shù)就會創(chuàng)建一個新的函數(shù)作用域
* - 在函數(shù)作用域中可以訪問到全局變量,
* 而在全局中無法訪問到函數(shù)作用域中的變量
* 在函數(shù)中創(chuàng)建的變量如果不寫var,則會變成全局變量
* - 當(dāng)我們在函數(shù)中使用一個變量時,它會先在自身的作用域中尋找,
* 如果有就直接使用,如果沒有則去上一級作用域中尋找,
* 找到則使用,沒找到則繼續(xù)尋找,直到找到全局作用域為止
* 如果全局作用域中依然沒有,則報錯ReferenceError
* - 在函數(shù)作用域中也適用變量和函數(shù)的聲明提前
js的閉包:能讓一個變量的生命周期變長。有內(nèi)外兩層函數(shù),外層函數(shù)返回一個內(nèi)層函數(shù),內(nèi)層函數(shù)引用了外層函數(shù)中定義的一個或多個變量,就形成了閉包。
//創(chuàng)建一個全局變量a
var a = "全局中的a";
function fun(){
//console.log(a);
//window.b = ...
var b = "---> 函數(shù)作用域中的b";
//console.log(b);
}
//fun();
//console.log(b);
//創(chuàng)建全局變量c
var c = "全局c";
console.log(window.c);
/*function fun2(){
//創(chuàng)建一個局部變量c
var c = "---> 函數(shù)中的c";
console.log(c);
}
fun2();*/
function fun3(){
//var c = "fun3中的c";
function fun4(){
//var c = "fun4中的c";
console.log(c);
}
//調(diào)用fun4
fun4();
}
//fun3();
類的定義
//class關(guān)鍵字必須是小寫。 后面就是跟的類名
class PersonClass {
// 等效于 PersonType 構(gòu)造函數(shù)。
constructor(name) { //這個表示類的構(gòu)造函數(shù)。constuctor也是關(guān)鍵字必須小寫。
this.name = name; //創(chuàng)建屬性。 也叫當(dāng)前類型的自有屬性。
}
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); //相當(dāng)于以前的:Father.call(this, name);
this.age = age;
}
//子類獨有的方法
sayAge(){
console.log(this.age);
}
//子類中的方法會屏蔽到父類中的同名方法。
sayName(){
super.sayName(); //調(diào)用被覆蓋的父類中的方法。
console.log("我是子類的方法,我屏蔽了父類:" + name);
}
}
var son1 = new Son("李四", 30);
son1.sayAge();
son1.sayName();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
var person = {};
person.name = 'zhangsan';
person.age = 32;
person.sayHello = function () {
alert('hello');
}
person.sayHello();
var car = {};
car.color = 'red';
alert(car.color);
alert(person.name);
</script>
</head>
<body>
</body>
</html>