javascriptは関数を深く理解します.

8197 ワード

javascriptは関数を深く理解します.
関数宣言方法
1.function関数宣言文
function add(a,b){
    return a+b;
}
console.log(add(1,2));
2.関数式
var add = function (a,b) {
    return a+b;
}
console.log(add(3,2));
3.コンストラクタ
Functionキーの前のパラメータは関数のイメージです.最後のパラメータは戻り値です.
var add = new Function("a","b","return a+b");
console.log(add(5,6));
関数参照
関数呼び出し時には、任意の複数の参照が入力できます.関数定義時には、任意の複数の参照を定義することもできます.
//    
function func1() {
    //   arguments        
    console.log(arguments);
}  
func1(1,"a",{"name":"apple"});

//    
function func2(a,b,c) {
    //               ,    undefined
    console.log(a,b,c);
}
func2(1,2);
関数の参照の種類
データタイプは、基本データタイプと参照データタイプの基本データタイプに分けられます.変数に直接データの値を格納します.例えば、Number、String、Boolean、undefined、null参照データタイプ:変数に格納されているのはデータの住所です.変数内容を取得する場合、データのアドレスから該当位置のデータを検索します.例えば、Objectなどの関数が入力された場合、データの値を伝値形式でコピーして、参照データタイプとして形参関数に入力した場合、転送先の形式でデータのアドレスをコピーします.
//   :               
var num = 0;
function setNum(n) {
    n = 100;
    console.log(n); // 100
}
setNum(num);
console.log(num); // 0

//   :                   
//      
var person = {
    name:"alex",
    age:18
}
function setAge(obj) {
    obj.age = 20;
    console.log(obj.age);  // 20
}
setAge(person); 
console.log(person.age); // 20

//    
var person = {
    name:"alex",
    age:18
}
function setAge(obj) {
    obj = {
    name:"apple",
    age:33
}
    console.log(obj.age);  // 33
}
setAge(person); 
console.log(person.age); // 18
アドレス:関数の実際の参person-」は、関数の形参objの次のステップにおける実例をコピーします.一:関数の形参に格納されているのは、personオブジェクトのアドレスです.アドレスを通じて、personオブジェクトを見つけ、ageケースを修正します.二:関数の形参に記憶されているアドレスは、新しいオブジェクトのアドレスに変更されます.したがって、現在のobj変数は、person変数とは関係がありません.Obj変数に格納されているアドレスは新しいオブジェクトアドレスです.
関数の名前変更
jsには関数の再ロードという言い方がありません.形参と実参には数と種類の制限がありません.関数の名前が重い場合、非厳密モードで最後に定義された同名の関数は前の定義を上書きします.厳格モードは次回エラーとなります.
function add(a,b) {
    console.log("add1");
    return a+b;
}
function add() {
    console.log("add2");
    return arguments[0]+arguments[1];
}
add();
関数の再ロード事例
add関数は、パラメータを入力しなくてもいいです.リストに入力して、合計を求めることができます.パラメータの合計を求めることができます.
function add() {
    //1.       ,    
    if(!arguments.length){
        return 0;
    }else{
        var arr = null;
        //2.             ,       
        if(Array.isArray(arguments[0])){
            arr = arguments[0];
        }else{
            arr = Array.apply(null,arguments);
        }
        //   :        for    
        // reduce     arr  ,        
        // total       ,num     
        var result = arr.reduce(function(total,num){
            return total + num;
        })
        return result;
    }
}
console.log(add());
console.log(add([1,2,6,7]));
console.log(add(1,2,134));
関数の戻り値
関数にreturn文がない場合、デフォルトはundefined returnに戻ります.任意の値を返します.
//   return  ,    undefined
function func1(a,b) {
    var c = a / b;
}
console.log(func1(1,2));

// return            
function func2(a,b) {
    return a+b;
}
console.log(func2(1,3));
new文の関数の戻り値
new関数オブジェクトを使用すると、そのreturnがオブジェクトでない場合や値を返していない場合、デフォルトはconstructorコンストラクタオブジェクトです.
// new     ,        
function func3(a,b) {  
    var c = a + b;
}
var func = new func3();  //        
console.log(func); //       

function func4(a,b) {  
    var c = a + b;
    return {
        "a":111
    }
}
var func = new func4();  //        
console.log(func); //       
特例
一般的にreturn文が指し示したら、後の文は実行されませんが、try{}catch(){}文があれば、特別な状況が発生します.
//   1:        ,      return  
function func(){
    try{
        var a = 1;
        console.log(b);  //   ,   catch  
        return 0;
    }catch(err){
        console.log(err);  // ReferenceError: b is not defined
        return 1;
    }
}
console.log(func()); // 1

//    : finally ,try   return    
function func1() { 
    try{
        var a = 1;
        return 0;
    }catch(e){
        console.log(e);
        return 1;
    }finally{
        return 2;
    }
}
console.log(func1());  // 2  
関数の呼び出し方法
直接呼び出し
関数名+小かっこを直接使うと、関数を呼び出すことができます.
// ()    
function add(a,b) {
    return a+b;
}
console.log(add(1,2));

//       
obj = {
    name:"alex",
    say:function(){
        console.log(this.name);
    }
}
obj.say();

// new   ,        
var myFunc = new add;
console.log(myFunc);
間接呼び出し
主にcall()の方法とappy()の方法があります.
//     
// call(this     ,  1,  2...)        
function add(a,b) {
    return a+b;
}
//         null, this    
console.log(add.call(null,1,3));

// apply(this     ,[    ])
function sum(a,b,c) {
    return a+b+c;
}
console.log(sum.apply(obj,[1,3,5]));
各関数には、継承されていない方法のapply()とcall()の2つの方法があります.最初のパラメータがnull、undefinedに入ったとき、関数thisはグローバルオブジェクトの厳密モードに向けて、値を指定しなければなりません.
関数の属性
fn.lengthは、関数の参照数fn.nameを返します.関数名fn.prototypeは、関数の親オブジェクトです.
function add(a,b) {
    return a+b;
}
console.log(add.length); // 2
console.log(add.name); // add
console.log(add.prototype);  // {constructor: ƒ} 

//      ,name     
var sum = function (a,b) {
    return a+b;
}
console.log(sum.name); // sum

//      ,name     
var hi = function hello() {
    // hello             ,       
    console.log(hello.name);
    return 0;
}
// hello();  //   :07     .html:22 Uncaught ReferenceError: hello is not defined
hi();  // hello
console.log(hi.name); // hello
関数の方法
bindメソッド使用
関数にthisを付けるオブジェクト
// find     this  
var name = "alex";
var obj = {
    name:"apple"
}
function fn() {
    console.log(this.name);  //   this  window
}
fn();  // alex
var gn = fn.bind(obj);  //  this  obj  
gn(); // apple
ケース2
bindの最初のパラメータはthisオブジェクトの指向で、後のパラメータは関数のパラメータです.
function func1(name,age,fav) {
    var str = "my name is "+name+",I am "+age+",I like "+fav;
    console.log(str);
}
//         
var part1 = func1.bind(null,"alex");
part1(18,"comic");   // my name is alex,I am 18,I like comic
part1(22,"animation"); // my name is alex,I am 22,I like animation

//         
var part2 = func1.bind(null,"egon",22);
part2("html");   // my name is egon,I am 22,I like html
part2("javascript");   // my name is egon,I am 22,I like javascript
これは関数式プログラミングの一種です.関数コリックはpythonの偏り関数に似ています.
callとappyの応用
実例1:配列中の最大要素を見つける
// 1.         
function max(arr) {  
    // Math.max()              
    //        Math.max(6,9,5)    9
    var res = Math.max.apply(null,arr);
    return res;
}
console.log(max([1,9,8,7,6,5])); // 9
2.クラス配列を本物の配列に変換する
//   :arguments     ,            ,         
function toArr() {  //   :        ,      
    var arr = Array.prototype.slice.call(arguments);
    return arr;
}
配列のプロトタイプには、slice方法があり、sliceスライスは、配列の一部を取得することができる.例えば、[1,2,3,4,5].slice(2,4)に戻り、[3,4]に戻り、パラメータが入ってこない場合、元のような要素の新しい配列(浅いコピー)が一つのパラメータに入ってきたとき、インデックスからすべての要素の配列が二つのパラメータに入ったときに、始点から終点まで戻る(含まない).間の要素
3.配列追加
push方法では、配列の最後にパラメータを挿入する方法arr1.push(6,8)は、以下の動作に等しい.
// 3.    :                    
function extend(arr1,arr2) {
    //    arr1.push.apply(arr2);  arr1    
    return Array.prototype.push.apply(arr1,arr2);
}
arr1 = [1,2,3];
arr2 = [6,8];
console.log(extend(arr1,arr2)); // [1,2,3,6,8]
pythonリストを実現するためのexted方法と似ています.
4.callとappyで相続する
person = {
    name:"apple",
    age:18
}
function Info(name,age) {
    this.name = name;
    this.age = age;
    this.sayAge = function () {
        console.log(this.age);
    }
}
//          
var egg = new Info("egg",15);
egg.sayAge()  // 15

//   call  this  ,    person  
console.log(person);  // {name: "banana", age: 20, sayAge: ƒ}
Info.call(person,"banana",20);
console.log(person);
person.sayAge(); // 20  

5.appply方法関数の呼び出し方法を変更する
// apply          
function Log() {
    console.log.apply(null,arguments); //            console.log()   
}
Log("hello console.log"); //hello console.log