js函數操作

在js中,函數本身屬于對象的一種,因此可以定義、賦值,作為對象的屬性或者成為其他函數的參數。函數名只是函數這個對象類的引用。

函數定義

3種函數定義的方式
1.函數聲明語句
使用function關鍵字,后跟一組參數以及函數體

function funcname(args1,args2){
 statement;
}

2.函數表達式
以表達式方式定義的函數,函數的名稱是可選的

var  funcname=function(args1,args2){
statement;
}
var funcname=function funcname(args1,args2){
statement;
}

匿名函數也叫拉姆達函數,是function關鍵字后面沒有標識符的函數。
通常而言,以表達式定義函數時都不需要名稱,這會讓定義它們的代碼更加緊湊。函數表達式特別適合用來定義那些只會使用一次的函數

var ten=(function(x){return x*x}(10));//定義同時進行調用

一個函數定義表達式包含名稱,函數的局部作用域將會包含一個綁定到函數對象的名稱。實際上,函數的名稱將成為函數內部的一個局部變量。

var test=function fn(){
  return fn;
}
console.log(test);//fn(){return fn;}
console.log(test());//fn(){return fn;}
console.log(test()());//fn(){return fn;}

對于有具體名字的函數表達式來說,函數名稱相當于函數對象的形參,自能在函數內部使用;而變量名稱相當于函數對象的實參,在函數內部和函數外部都可以使用。

var test=function fn(){
  return fn===test;
}
console.log(test());//true
console.log(test===fn);//fn is not defined

函數定義了一個非標準的name屬性,通過這個屬性可以訪問到給定函數指定的名字,這個屬性的值永遠等于跟在function關鍵字后面的標識符,匿名函數的name屬性為空。

//ie-11瀏覽器無效,輸出undefined
//chrome在處理匿名函數時有問題,會顯示函數表達式的名字
function fn(){}
console.log(fn.name);//fn
var fn=function(){};//''在chrome瀏覽器會顯示fn
var fn=function abc(){}
console.log(fn.name);//abc

3.function構造函數
Function構造函數接收任意數量的參數,但是最后一個參數始終都被看成是函數體,而前面的參數則枚舉出了新函數的參數

var funcname=new Function(args1,args2,'statement')

注意:Function構造函數無法指定函數名稱,它創建的是一個匿名函數。
從技術上講,這是一個函數表達式。但是不推薦使用這種方式聲明函數,這種語法會導致解析兩次代碼。第一次是解析常規js代碼,第二次解析傳入構造函數中的字符串,影響性能。

var sum=new Function('num1','num2','return num1+num2')
//等價于
var sum=function(num1,num2){
  return num1+num2;
}

Function()構造函數創建的函數,其函數體的編譯總是會在全局作用域中執行。于是,Function()構造函數類似于在全局作用域中執行的eval()

var test=0;
functoin fn(){
  var test=1;
  return new Function('return test')
}
console.log(fn()());//0

并不是所有的函數都可以成為構造函數

var a=new Math.min();//報錯

函數聲明順序

函數聲明,相對于變量會優先加載。所以不用擔心函數聲明在調用前還是調用后。
調用函數時會在本機活動對象中查詢,即當前js文件中查詢,如果沒有才會向上查詢
,所以要是在兩個js文件中定義相同的函數名,這兩個js文件內部調用各自的函數,其他js文件調用最后聲明的函數。

重復

變量的重復聲明是無用的,不會覆蓋同一作用域聲明的變量,但是函數的重復聲明會覆蓋前面的同名函數或同名變量。

//變量的重復聲明無用
var a=1;
var a;
console.log(a);//1
//覆蓋同名變量
var a;
function a(){
  console.log(1)
}
a();//1
//覆蓋同名函數
a();//2
function a(){
  console.log(a)
}
function a(){
  console.log(2)
}

刪除

函數聲明語句創建的變量無法刪除,這一點和變量聲明一樣。

function foo(){
  console.log(1)
}
delete foo;
console.log(foo());//1

函數返回值

所有函數都有返回值,沒有return語句時,默認返回內容是undefined,和其他面向對象的編程語言一樣,return語句不會阻止finally子句的執行。

function test(){
  try{
      return 2;
}catch(error){
  return 1;
}finally{
  return 0;
}
}
test();//0

如果函數調用時在前面加上了new前綴,且返回值不是一個對象,則返回this(該新對象)

function fn(){
    this.a=2;
    return 1;
}
var test=new fn();
console.log(test);//{a:2}
console.log(test.constructor);//fn(){this.a=2;return 1;}

如果返回值是一個對象,則返回該對象。

function fn(){
  this.a=2;
  return {a:1}
}
var test=new fn();
console.log(test);//{a:1}
console.log(test.constructor);//Object

函數調用

js一共有四種調用模式:函數調用模式,方法調用模式,構造器調用模式和間接調用模式。
1.函數調用模式
當一個函數并非一個對象的屬性時,那么他就是被當作一個函數來調用的。對于普通的函數調用來說,函數的返回值就是調用表達式的值。

function add(x,y){
 return x+y;
}
var sum=add(3,4)
console.log(sum);//7

使用函數調用模式調用函數時。非嚴格模式下,this被綁定到全局對象;在嚴格模式下,this是undefined

function add(x,y){
  console.log(this);//window
}
function add(x,y){
  'use strict';
  console.log(this);//undefined
}

因此,this可以用來判斷當前是否是嚴格模式。

var strict=(functioon(){return !this;}())

重寫:因為函數調用模式的函數中的this綁定到全局對象,所以會發生全局屬性被重寫的現象

var a=0;
function fn(){
  this.a=1;
}
fn();
console.log(this,this.a,a);//window 1 1

2.方法調用模式
當一個函數被保存為對象的一個屬性時,我們稱它為一個方法。當一個方法被調用時,this被綁定到該對象。如果調用表達式包含一個提取屬性的動作,那么它就是被當作一個方法來調用。

var o={
    m:function(){
      console.log(1)
  }
}
o.m();//1

方法可以使用this訪問自己所屬的對象,所以它能從對象中取值或對對象進行修改。this到對象的綁定發生在調用的時候。通過this可取的它們所屬對象的上下文的方法稱為公共方法。

var o={
  a:1,
  m:function(){
      return this;
},
  n:function(){
    this.a=2;
}
}
console.log(o.m().a);//1
o.n();
console.log(o.m().a);//2

任何函數只要作為方法調用實際上都會傳入一個隱式的實參--這個參數是一個對象,方法調用的母體就是這個對象,通常來講,基于那個對象的方法可以執行多次操作,方法調用的語法已經清晰的表明了函數將基于一個對象進行操作。

rect.setSize(width,height);
setRectSize(rect,width,height);

假設上面兩行代碼的功能完全一樣,它們都作用于一個假定的對象rect。可以看出,第一行的方法調用語句非常清晰的表明這個函數執行的載體是rect對象,函數中的所有操作將會基于這個對象。
和變量不同,關鍵字this沒有作用域的限制,嵌套的函數不會調用它的函數中繼承this,如果嵌套函數作為方法調用,其this的值指向調用它的對象。如果嵌套函數作為函數調用,其this的值不是全局對象就是undefined

var o={
  m:function(){
    function n(){
        return this;
}
return n();
}
}
console.log(o.m());//window
var o={
  m:function(){
    function n(){
        'use strict'
return this;
}
return n()
}
}
console.log(o.m());//undefined

如果想訪問這個外部函數的this值,需要將this的值保存在一個變量里,這個變量和內部函數都同在一個作用域內。通常使用變量self或that來保存this.

var o={
 m:function(){
  var self=this;
  console.log(this===o);//true
  function n(){
    console.log(this===o);//false
    console.log(self===o);//true
    return self;  
}  
    return n()
}
}
console.log(o.m()===o);//true

3.構造函數調用模式
如果函數或者方法調用之前帶有new關鍵字,它就構成構造函數調用。

function fn(){
  this.a=1;
}
var obj=new fn();
console.log(obj.a);//1

如果構造函數調用在圓括號內包含一組實參列表,先計算這些實參表達式,然后傳入函數內

function fn(x){
    this.a=x;
}
var obj=new fn(2);
console.log(obj.a);//2

如果構造函數沒有形參,js構造函數調用的語法是允許省略實參列表和圓括號的。凡是沒有形參的構造函數都可以省略圓括號。

var o=new Object();
//等價于
var o=new Object;

注意:盡管構造函數看起來像是一個方法調用,他依然會使用新對象作為調用上下文。也就是說:在表達式new o.m()中,調用上下文并不是o

var o={
  m:function(){
    return this;
}
}
var obj=new o.m();
console.log(obj,obj===o);//{},false
console.log(obj.constructor===o.m);//true

構造函數通常不使用return關鍵字,他們通常初始化新對象,當構造函數的函數體執行完畢時,它會顯式返回。在這種情況下,構造函數調用表達式的計算結果就是這個新對象的值。

function fn(){
  this.a=2;
}
var test=new fn();
console.log(test);//{a:2}

如果構造函數使用return語句但沒有指定返回值,或者返回一個原始值,那么這時將忽略返回值,同時使用這個新對象作為調用結果

function fn(){
    this.a = 2;
    return;
}
var test = new fn();
console.log(test);//{a:2}

如果構造函數顯式地使用return語句返回一個對象,那么調用表達式的值就是這個對象

var obj = {a:1};
function fn(){
    this.a = 2;
    return obj;
}
var test = new fn();
console.log(test);//{a:1}

4.間接調用模式
js中函數也是對象,函數對象也可以包含方法,call()和apply()方法可以用來間接的調用函數。
這兩個方法都允許顯式指定調用所需的this值,也就是所,任何函數可以作為任何對象的方法來調用,哪怕這個函數不是對象的方法。兩個方法都可以指定調用的實參。call()方法使用它自有的實參列表作為函數的實參。apply()方法則要求以數組的形式傳入參數。

var obj={};
function sun(x,y){
  return x+y;
}
console.log(sun.call(obj,1,2));//3
console.log(sun.apply(obj,[1,2]));//3

函數參數

arguments:js中的函數定義并未指明函數形參的類型,函數調用也未對傳入的實參值做任何類型檢查。實際上,js函數調用甚至不檢查傳入形參的個數。

function add(x){
  return x+1;
}
console.log(add(1));//2
console.log(add("1"));//11
console.log(add());//NaN
console.log(add(1,2));//2

同名形參:在非嚴格模式下,函數中可以出現同名形參,且只能訪問最后出改名稱的形參。

function add(x,x,x){
  return x;
}
console.log(add(1,2,3));//3

而在嚴格模式下,出現同名形參拋出語法錯誤。

function add(x,x,x){
  'use strict';
  return x;
}
console.log(add(1,2,3));//出現錯誤

參數個數:當實參比函數聲明指定的形參個數少,剩下的形參都將設置為undefined值。

function add(x,y){
  console.log(x,y);
}
add(1);//1,undefined

常常使用邏輯或運算符給省略的參數設置一個合理的默認值。

function add(x,y){
  y=y||2;
  console.log(x,y)
}
add(1)

注意:實際上,使用y=y||2是不嚴謹的,顯示的設置值(undefined,null,false,0,-0,NaN)也會得到相同的結果。所以應該根據實際場景進行合理設置。
當實參比形參個數要多時,剩下的實參沒有辦法直接獲得,需要使用即將提到的arguments對象。
js中的參數在內部用一個數組表示。函數接收到的始終都是這個數組,而不關心數組中包含哪些參數。在函數體內可以通過arguments對象來訪問這個參數數組,從而獲得傳遞給參數的每一個參數。arguments對象并不是array的實例,他是一個類數組對象,可以使用方括號訪問它的每一個元素。

function add(x){
  console.log(arguments[0],arguments[1],arguments[2]);
 return x+1;
}
add(1,2,3)

arguments對象的length屬性顯示實參的個數,函數的length屬性顯示形參的個數。

function add(x,y){
  console.log(arguments.length) //3
  return x+1;
}
add(1,2,3);
console.log(add.length); //2

形參只是提供便利,但不是必需的

function add(){
     return arguments[0]+arguments[1];
}
console.log(add(1,2));//3

對象參數:當一個函數包含超過3個形參時,要記住調用函數中實參的正確順序實在讓人頭疼。

function arraycopy(/*array*/from,/*index*/form_start,/*array*/to,/*index*/to_start,/*integer*/length){
  //todo
}

通過鍵值對的形式來傳入參數,這樣參數的順序就無關緊要了。定義函數的時候,傳入的實參都寫入一個單獨的對象之中,在調用的時候傳入一個對象,對象中的名值對是真正需要的實參數據。

function easycopy(args){
  arraycopy(args.from,args.from_start||0,args.to,args.to_start||0,args.length);
}
var a=[1,2,3,4],b=[];
easycopy({from:a,to:b,length:4})

以參數為參數
函數本身是一個對象,因此可以將函數作為另一個函數的參數,進而實現函數回調,功能等同于c++中的函數指針

function printf(str){
  dom1.innerText+=str.toString()+"\n";//設置dom1顯示的文字。變量也可以自動調用其他js文件中的dom1變量。dom1會先在當前文件中查詢,然后向之前引用的js文件查詢,再向之后引用的js文件查詢
}
function callfunction(myfunction,myargument){           //函數作為其他函數的參數
    return myfunction(myargument);                      //調用回調函數
}

callfunction(printf,"hello world");

同步:當形參與實參的個數相同時,arguments對象的值和對應形參的值保持同步。

function test(num1,num2){
  console.log(num1,arguments[0]);//1,1
arguments[0]=2;
console.log(num1,arguments[0]);//2,2
num1=10;
console.log(num1,arguments[0]);//10,10
}
test(1)

注意:雖然命名參數和對應arguments對象的值相同,但并不是相同的命名空間。他們的命名空間是獨立的,但值是同步的
在嚴格模式下,arguments對象的值和參數的值都是獨立的。

function test(num1,num2){
  'use strict';
console.log(num1,arguments[0]);1,1
arguments[0]=2;
console.log(num1,arguments[0]);1,2
num1=10;
console.log(num1,arguments[0]);10,2
}
test(1)

當形參并沒有對應的實參時,arguments對象的值和形參的值并不對應。

function test(num1,num2){
  console.log(num1,arguments[0]);//undefined,undefined
num1=10;
arguments[0]=5;
console.log(num1,arguments[0]);//10,5
}
test()

內部屬性:callee
arguments對象有一個名為callee的屬性,該屬性是一個指針,指向擁有這個arguments對象的函數
下面是經典的階乘函數

function factorial(num){
  if(num<=1){
    return 1;
  }else{
    return num*factorial(num-1)
   }
}
console.log(factorial(5));//120

但是,上面這個函數的執行與函數名字緊緊耦合在了一起,可以使用arguments.callee可以消除函數解耦

function fact(num){
  if(num<=1){
    return 1;
}else{
  return num*arguments.callee(num-1);
}
}
console.log(fact(5));//120

但是在嚴格模式下,訪問這個屬性會拋出typeerror錯誤

function factorial(num){
    'use strict';
    if(num <=1){
        return 1;
    }else{
        return num* arguments.callee(num-1);
    }
}    
//TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them
console.log(factorial(5));

這時,可以使用具名的函數表達式

var fact=function fn(num){
  if(num<=1){
    return 1;
}else{
  return num*fn(num-1)
}
}
console.log(fact(5))

caller:實際上,有兩個caller屬性
1:函數的caller
函數的caller屬性保存著調用當前函數的函數的引用,如果實在全局作用域中調用當前函數,它的值是null

function outer(){
  inner()
}
function inner(){
  console.log(inner.caller)//outer(){inner();}
}
outer()
function inner(){
  console.log(inner.caller);//null
}
inner()

在嚴格模式下,訪問這個屬性會拋出typeerror錯誤

function inner(){
  'use strict';
  console.log(inner.caller);
}
inner()

2:arguments對象的caller
該屬性始終是undefined,定義這個屬性是為了分清arguments.caller和函數的caller屬性

function inner(x){
    console.log(arguments.caller);//undefined
}
inner(1);

同樣地,在嚴格模式下,訪問這個屬性會拋出TypeError錯誤

function inner(x){
    'use strict';
    //TypeError: 'caller' and 'arguments' are restricted function properties and cannot be accessed in this context
    console.log(arguments.caller);
}
inner(1);

函數重載

js函數不能像傳統意義上那樣實現重載。而在其他語言中,可以為一個函數編寫兩個定義,只要這兩個定義的簽名(接受的參數的類型和數量)不同即可。
js函數沒有簽名,因為其參數是由包含0個或者多個值得數組來表示的。而沒有函數簽名,真正的重載是不可能做到的。

//后面的聲明覆蓋了前面的聲明
function a(num){
  retun num+100;
}
functiona (num){
  return num+200;
}
var result=a(100);//300

只能通過檢查傳入函數中參數的類型和數量并做出不同的反應,來模仿方法的重載

function doAdd(){
  if(arguments.length==1){
    alert(arguments[0]+10)
}else if(arguments.length==2){
    alert(arguments[0]+arguments[2])
}
}
doAdd(10);//20
doAdd(30,20);//50

參數傳參

js中所有函數的參數都是按值傳遞的,也就是說,把函數外部的值復制到函數內部的參數,就和把值從一個變量復制到另一個變量一樣。
1.基本類型值
在向參數傳遞基本類型的值時,被傳遞的值會被復制給一個局部變量(同名參數或arguments對象的一個元素)

function addTen(num){
  num+=10;
  return num;
}
var count=20;
var result=addTen(count);
console.log(count);//20
console.log(result);//30

2.引用類型值
在向參數傳遞引用類型的值時,會把這個值在內存中的地址復制給一個局部變量,因此這個局部變量的變化會反應在函數的外部。

function setName(obj){
    obj.name="test"
}
var person=new Object();
setName(person)
console.log(person.name);//test

當在函數內部重寫引用類型的參數時,這個變量的引用就是一個局部對象了。而這個局部對象會在函數執行完畢后立即被銷毀。

function setName(obj){
  obj.name="test";
  console.log(person.name);//test
  obj=new Object();
  obj.name="white";
  console.log(person.name);//test
}
var person=new Object();
setName(person)

函數屬性

length屬性
arguments對象的length屬性表示實參個數,而函數的length屬性則表示形參個數。

function add(x,y){
    console.log(arguments.length)//3
    console.log(add.length)//2
}
add(1,2,3)

name屬性
函數定義了一個非標準的name屬性,通過這個屬性可以訪問到給定函數指定的名字,這個屬性的值永遠等于跟在function關鍵字后面的標識符,匿名函數的name屬性為空

//IE11-瀏覽器無效,均輸出undefined
//chrome在處理匿名函數的name屬性時有問題,會顯示函數表達式的名字
function fn(){};
console.log(fn.name);//'fn'
var fn = function(){};
console.log(fn.name);//'',在chrome瀏覽器中會顯示'fn'
var fn = function abc(){};
console.log(fn.name);//'abc'  

注意:name屬性早就被瀏覽器廣泛支持,但是直到es6才將其寫入標準
es6對這個屬性的行為做出了一些修改,如果將一個匿名函數賦值給一個變量,es5的name屬性會返回空字符串,而es6的name屬性會返回實際的函數名

var fun=function(){}
fun.name;//es5 ""
fun.name;//es6 fun

如果將一個具名函數賦值給一個變量,則es5和es6的name屬性都返回這個具名函數原本的名字

var bar=function baz(){}
bar.name;//es5 baz
bar.name;//es6 baz

Function構造函數返回的函數實例,name屬性的值是“anonymous”

(new Function).name;//anonymous

bind返回的函數,name屬性值會加上“bound”前綴

function foo(){}
foo.bind({}).name;//bound foo
(function (){}).bind({}).name;//bound

prototype屬性
每一個函數都有一個prototype屬性,這個屬性指向一個對象的引用,這個對象稱作原型對象。每一個函數都包含不同的原型對象。將函數用作構造函數時,新創建的對象會從原型對象上繼承屬性

function fn(){}
var obj=new fn;
fn.prototype.a=1;
console.log(obj.a);//1

函數方法

apply()和call()
每個函數都包含兩個非繼承而來的方法,apply()和call().這兩個方法的用途都是在特定的作用域中調用函數,實際上等于函數體內this對象的值。
要想以函數對象o的方法來調用函數f(),可以這樣使用call()和apply()

f.call(o)
f.apply(o)

假設o中不存在m方法,則等價于

o.m = f; //將f存儲為o的臨時方法
o.m(); //調用它,不傳入參數
delete o.m; //將臨時方法刪除

下面是一個實際的例子

window.color="red";
var o={color:"blue"};
function saycolor(){
  console.log(this.color)
}
sayColor()//red
sayColor.call(this);//red
sayColor.call(window);//red
sayColor.call(o);//blue
//sayColor.call(o)等價于
o.sayColor=sayColor;
o.sayColor();//blue
delete o.sayColor;

apply()方法接收兩個參數:一個是在其中運行函數的作用域(或者可以說是要調用函數的母對象,它是調用上下文,在函數體內通過this來獲得對他的引用),另一個是參數數組。其中,第二個參數可以是array的實例,也可以是arguments對象

function sum(num1,num2){
  return num1+num2;
}
//因為運行函數的作用域是全局作用域,所以this代表的是window對象
function callSum(num1,num2){
  return sum.apply(this,arguments)
}
function callSum2(num1,num2){
  return sum.apply(this,[num1,num2])
}
console.log(callSum(10,10));//20
console.log(callSum2(10,10));//20

call()方法與apply()方法的作用相同,它們的區別僅僅在于接收參數的方式不同,對于call方法而言,第一個參數是this值沒有變化,變化的是其余參數都直接傳遞給函數。換句話說,在使用call()方法時,傳遞給函數的參數必須逐個列舉出來

function sum(num1, num2){
    return num1 + num2;
}
function callSum(num1, num2){
    return sum.call(this, num1, num2);
}
console.log(callSum(10,10));   //20

至于是使用apply()還是call(),完全取決于采取哪種函數傳遞參數的方式最方便。如果打算直接傳入arguments對象,或者包含函數中先接收到的也是一個數組,那么使用apply()肯定更方便,否則,選擇call()可能更合適
在非嚴格模式下,使用函數的call()或apply()方法時,null或undefined值會被轉換為全局對象。而在嚴格模式下,函數的this值始終是指定的值

var color = 'red';
function displayColor(){
    console.log(this.color);
}
displayColor.call(null);//red
var color = 'red';
function displayColor(){
    'use strict';
    console.log(this.color);
}
displayColor.call(null);//TypeError: Cannot read property 'color' of null

應用

1.調用對象的原生方法

var obj={};
obj.hasOwnProperty("toString");//false
obj.hasOwnProperty=function(){
  return true;
}
obj.hasOwnProperty("toString");//true
Object.prototype.hasOwnProperty.call(obj,"toString");false

2.找出數組中的最大值
js不提供找出數組最大元素的函數,結合使用apply方法和math.max方法,就可以返回數組的最大元素

var a=[1,33,2,4,5,6];
Math.max.apply(null,a)

3.將數組對象轉換成真正的數組

Array.prototype.slice.apply({0:1,length:1})//[1]
或者
[].prototype.slice.apply({0:1,length:1})

4.將一個數組的值push到另一個數組中

var a=[];
Array.prototype.push.apply(a,[1,2,3])
console.log(a);//[1,2,3]
Array.prototype.push.apply(a,[2,3,4]);
console.log(a);//[1,2,3,2,3,4]

5.綁定回調函數的對象
由于apply方法或者call方法不僅綁定函數執行時所在的對象,還會立即執行函數,因此不得不把綁定語句寫在函數體內,更簡潔的寫法是采用下面的bind方法

var o={};
o.f=function(){
    console.log(this===o)
}
var f=function(){
  o.f.apply(o)
}

bind()方法
bind()是es5新增的方法,這個方法的主要作用是將函數綁定到某個對象上
當在函數f()上調用bind()方法并傳入一個對象o作為參數,這個方法將返回一個新的對象。以函數調用的方式調用新的函數將會把原始的函數f()當作o的方法調用,傳入新函數的任何實參都將傳入原始函數

function f(y){
  return this.x+y;
}
var o={x:1};
var g=f.bind(o);
g(2)

兼容代碼

function bind(f,o){
  if(f.bind){
  return f.bind(o)
}else{
  return function(){
  return f.apply(o,arguments)
}
}
}

bind方法不僅是將函數綁定到一個對象上,它還附帶一些其他應用:除了第一個實參外,傳入bind的實參也會綁定到this,這個附帶的應用是一種常見的函數式編程及時,稱柯里化

var sum=function(x,y){
  return x+y;
}
var succ=sum.bind(null,1);
succ(2);//3,x綁定到1,并傳入2作為實參y
function f(y,z){
  return this.x+y+z;
}
var g=f.bind({x:1},2)
g(3);//6,this.x綁定到1,y綁定到2,z綁定到3

function getConfig(colors,size,other){
  console.log(colors,size,other)
}
var default=getConfig.bind(null,"#000","1024*234");
default("123")
default("456")

toString()
函數的toString()實例方法返回函數代碼的字符串,而靜態的toString()方法返回一個類似’[native code]’的字符串作為函數體

function test(){
  alert(1)
}
test.toString()
Function.toString()

toLocalString()
toLocalString()方法和toString()方法返回的結果相同

function test(){
    alert(1);//test
}
test.toLocaleString();/*"function test(){
                    alert(1);//test
                  }"*/
Function.toLocaleString();//"function Function() { [native code] }"
  

valueOf()
函數的valueOf()方法返回函數本身

function test(){
    alert(1);//test
}
test.valueOf();/*function test(){
                    alert(1);//test
                  }*/
typeof test.valueOf();//'function'
Function.valueOf();//Function() { [native code] }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容