js学习(4) 函数
JavaScript有三種聲明函數(shù)的方法
(1)function命令
function print(s) {console.log(s); }(2)函數(shù)表達(dá)式
1.var print = function(s) {console.log(s); };2.var print = function x(){console.log(typeof x); };x // ReferenceError: x is not definedprint() // function3.var f = function f() {};將匿名函數(shù)賦予變量,如果不匿名,也只在內(nèi)部有效
函數(shù)表達(dá)式定義函數(shù)最后要加上分號代表結(jié)束
(3)Function構(gòu)造函數(shù)
可以傳遞任意數(shù)量的參數(shù)給Function構(gòu)造函數(shù),但只有最后一個參數(shù)被當(dāng)做函數(shù)體
Function構(gòu)造函數(shù)可以不使用new命令,返回結(jié)果完全一樣
var add = new Function('x','y','return x + y' );// 等同于 function add(x, y) {return x + y; }此方法比較不常用 第一種方法倒更熟悉
如果一個函數(shù)被多次聲明,后面的聲明就會覆蓋前面的聲明
調(diào)用函數(shù)時和其他語言大致相同,使用圓括號運算符
第一等公民
Js把函數(shù)看成一種值,與其他值(數(shù)值,字符串,布爾值等)地位相同
凡是可以使用值的地方,就能使用函數(shù),函數(shù)只是一個可以執(zhí)行的值
function add(x, y) {return x + y; }// 將函數(shù)賦值給一個變量 var operator = add;// 將函數(shù)作為參數(shù)和返回值 function a(op){return op; } a(add)(1, 1) // 2函數(shù)提升
函數(shù)的屬性和方法
name屬性:返回函數(shù)名字 ?如果采用表達(dá)式定義函數(shù),且function后有名字,則返回那個名字
length屬性:返回函數(shù)預(yù)期傳入的參數(shù)個數(shù)
toString():返回一個字符串,內(nèi)容是函數(shù)的源碼,以及注釋
對于var命令來說,局部變量只能在函數(shù)內(nèi)部聲明,在其他區(qū)塊中聲明,一律都是全局變量
函數(shù)內(nèi)部也有變量提升,var命令聲明的對象,不管在什么位置,變量聲明都會被提升到函數(shù)體的頭部
函數(shù)本身的作用域
函數(shù)本身作用域就是聲明時所在的作用域,與運行時所在作用域無關(guān)
在定義時綁定作用域
var a = 1; var x = function () {console.log(a); };function f() {var a = 2;x(); }f() // 1函數(shù)的參數(shù)
可以省略,但沒辦法只省略靠前的參數(shù),而保留靠后的參數(shù),如果一定要省略靠前的參數(shù),只有顯式傳入undefined
參數(shù)傳遞對原值的影響
如果是原始類型的值,無影響,只是一份拷貝
如果傳入的是對象,則修改其屬性的話,原值會受到影響
但把對象整個替換掉,不會影響原始值,因為相當(dāng)于指向其他地址
同名參數(shù)
如果有同名參數(shù),則取最后出現(xiàn)的那個值
function f(a, a) {console.log(a); //a為最后一個a }f(1) // undefined 相當(dāng)于f(1,undefined)?
arguments對象
由于js允許函數(shù)提供不定數(shù)目的參數(shù),所以需要一種機制,可以在函數(shù)體內(nèi)部讀取所有參數(shù),這就是arguments對象的由來
arguments對象包含函數(shù)運行時所有參數(shù),使用類似數(shù)組
如果在非嚴(yán)格模式下還可以在函數(shù)內(nèi)部修改參數(shù)的值,嚴(yán)格模式下只讀
通過它的length屬性,可以判斷函數(shù)調(diào)用時到底帶了幾個參數(shù)
與數(shù)組關(guān)系:
是對象,不能使用數(shù)組方法,除非轉(zhuǎn)換為數(shù)組
var args = Array.prototype.slice.call(arguments);// 或者 var args = []; for (var i = 0; i < arguments.length; i++) {args.push(arguments[i]); }arguments自帶一個callee屬性1,返回它所對應(yīng)的原函數(shù),可以用這個寫遞歸
arguments每個函數(shù)運行時都有,無需顯式聲明
函數(shù)的閉包
閉包即能夠讀取其他函數(shù)內(nèi)部變量的函數(shù),可以簡單理解為“定義在一個函數(shù)內(nèi)部的函數(shù)”
用處:1.讀取函數(shù)內(nèi)部變量 2.記住誕生的環(huán)境
function createIncrementor(start) {return function () {return start++;}; }var inc = createIncrementor(5);inc() // 5 inc() // 6 inc() // 73.封裝對象的私有屬性和方法,感覺像類
function Person(name) {var _age;function setAge(n) {_age = n;}function getAge() {return _age;}return {name: name,getAge: getAge,setAge: setAge}; }var p1 = Person('張三'); p1.setAge(25); p1.getAge() // 25立即調(diào)用的函數(shù)表達(dá)式,聲明時就調(diào)用(IIFE)
(function(){ /* code */ }()); // 或者 (function(){ /* code */ })();所以以下寫法都行
var i = function(){ return 10; }(); true && function(){ /* code */ }(); 0, function(){ /* code */ }(); !function () { /* code */ }(); ~function () { /* code */ }(); -function () { /* code */ }(); +function () { /* code */ }();通常只對匿名函數(shù)使用
目的:1.不必命名,避免污染全局變量 2。在IIFE內(nèi)部形成了一個單獨的作用域,可以封裝一些外部無法讀取的私有變量
eval命令?
eval命令接受一個字符串作為參數(shù),并將這個字符串當(dāng)做語句執(zhí)行
eval('var a = 1;'); a // 1如果無法執(zhí)行就報錯
如果eval的參數(shù)不是字符串,那么會原樣返回
eval的作用域是當(dāng)前作用域,因此小心修改當(dāng)前作用域變量的值
eval本質(zhì)是在當(dāng)前作用域中注入代碼,由于安全風(fēng)險和不利于js引擎優(yōu)化執(zhí)行速度,一般不推薦使用
最常用的場合是解析json數(shù)據(jù)的字符傳遞,不過正確做法應(yīng)該使用原生的JSON.parse方法
js規(guī)定,凡是使用別名執(zhí)行eval,eval內(nèi)部一律是全局作用域
var a = 1;function f() {var a = 2;var e = eval;e('console.log(a)'); }f() // 1
?
轉(zhuǎn)載于:https://www.cnblogs.com/wtblogwt/p/10030250.html
總結(jié)
以上是生活随笔為你收集整理的js学习(4) 函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【TJOI/HEOI2016】求和
- 下一篇: 在VSCode中编写Kotlin/Jav