JavaScript 學習筆記 - Function


Posted by hata0833 on 2022-09-01

函數

聲明方法有3

  1. function 命令

    function print(s) {
    console.log(s);
    }
    
  2. 函数表达式

    var print = function(s) {
    console.log(s);
    };
    

    如果採用函數表達式聲明,給function 取的名字只能在函數內使用

    var print = function x(){
    console.log(typeof x);
    };
    x
    // ReferenceError: x is not defined
    print()
    // function
    
  3. Function 构造函数

    var add = new Function(
    'x',
    'y',
    'return x + y'
    );
    // 等同于
    function add(x, y) {
    return x + y;
    }
    

    可以传递任意数量的参数给Function构造函数,只有最后一个参数会被当做函数体,如果只有一个参数,该参数就是函数体。

函數作用域

函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。

var x = function () {
  console.log(a);
};
function y(f) {
  var a = 2;
  f();
}
y(x)
// ReferenceError: a is not defined

x的作用域在外層,訪問不到y中的a

省略參數

多傳或少傳參數,JavaScript都不會報錯,少傳的會帶入undefined

function f(a, b) {
  return a;
}
f(1, 2, 3) // 1
f(1) // 1
f() // undefined
f.length // 2 -> f預期接收的參數

但是,没有办法只省略靠前的参数,而保留靠后的参数。如果一定要省略靠前的参数,只有显式传入undefined。

function f(a, b) {
  return a;
}
f( , 1) // SyntaxError: Unexpected token ,(…)
f(undefined, 1) // undefined

傳參

var obj = [1, 2, 3];
function f(o) {
  o = [2, 3, 4]; // 重新對o賦值,把裡頭的o指向的地址更改了,不影響外面obj實際的值
}
f(obj);
obj // [1, 2, 3]

argument

由于 JavaScript 允许函数有不定数目的参数,所以需要一种机制,可以在函数体内部读取所有参数。这就是arguments对象的由来。
arguments对象包含了函数运行时的所有参数,arguments[0]就是第一个参数,arguments[1]就是第二个参数,以此类推。这个对象只有在函数体内部,才可以使用。
一般可以用argument改變參數的值,但是可以開啟嚴格模式切開聯動關係

var f = function(a, b) {
  arguments[0] = 3;
  arguments[1] = 2;
  return a + b;
}
f(1, 1) // 5
var f = function(a, b) {
  'use strict'; // 开启严格模式
  arguments[0] = 3;
  arguments[1] = 2;
  return a + b;
}
f(1, 1) // 2

argument vs array

虽然arguments很像数组,但它是一个对象。数组专有的方法(比如slice和forEach),不能在arguments对象上直接使用

callee

arguments对象带有一个callee属性,返回它所对应的原函数。

var f = function () {
  console.log(arguments.callee === f);
}

f() // true

可以通过arguments.callee,达到调用函数自身的目的。这个属性在严格模式里面是禁用的,因此不建议使用。

eval

eval命令接受一个字符串作为参数,并将这个字符串当作语句执行。
eval没有自己的作用域,都在当前作用域内执行,因此可能会修改当前作用域的变量的值,造成安全问题。

var a = 1;
eval('a = 2');

a // 2

閉包

可以讀取其他函數內的變量的函數
根據鏈式作用域(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

  1. 可以读取外层函数内部的变量
  2. 这些变量始终保持在内存中

closure w/ 鏈式作用域

https://mtr04-note.coderbridge.io/2020/09/26/about-closure/


#javascript







Related Posts

RWD

RWD

Day 12-Scope & Number Guessing Game

Day 12-Scope & Number Guessing Game

自動化測試 x Puppeteer - 玩偶QA參一咖 Day04

自動化測試 x Puppeteer - 玩偶QA參一咖 Day04


Comments