JavaScript函数基础知识

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hulk_oh/article/details/52839433

函数

函数的定义

函数可以通过关键字 function 来定义。实质上function 对象是 Function函数的实例化对象。

下面是定义的例子

function fn(args){ //关键字定义函数
    var vari = args;
    console.log(vari)
}
var fn = new Function( //通过构造函数 定义函数
'args',
'var vari = args;console.log(vari)'
)

函数的调用

函数的调用可以分为4种
1. 函数
2. 方法
3. 构造函数
4. call, apply 调用

函数调用

这里只做简单的例子说明,函数调用:

function a(){
    console.log(123)
}
a()// ===> 123

var some_var  = a() 
    some_var //===> 123

方法调用

一个方法 ,就是一个对象的属性里的 javascript函数。

var a = {} //JavaScript 对象
a.fn = function(){} // a对象的方法a
a.vari = 123; //a对象的属性vari

方法调用其实和调用函数一样,只不过我们调用的函数是对象里面的一个属性:

var example = function(){
    this.fn = function(){
        console.log('test')
    }
}
var obj = new exmaple();
obj.fn()// ===> test 

构造函数的调用

如果函数或者方法前面带有关键字 new,她就构成了构造函数调用。构造函数调用和普通的函数调用在实参处理,调用上下文和返回值方面都有不同;

var o = new Object();
var o = new Object;

构造函数调用会创建一个新的空对象,这个对象继承 继承 构造函数的prototype属性。

var con = function(){
    this.asd = 123;
}
con.prototype = {
    test:'this is con's prototype'
}
var c_obj  = new con();
    c_obj.test() // ====> 'this is con's prototype'

构造函数试图初始化这个新创建的对象,并将这个对象做其调用上下文,因此构造函数可以使用this关键字来引用这个新对象。

间接调用

对象名称 [类型]参数 默认 必填 [类型]返回 描述
call object,arg1, arg2, ,argN window / call(object,arg1,…argN)
apply [对象]object,[array][arg1, arg2, ,argN] window / / apply(object,arg1,…argN)
function a(){}
a.call();

函数属性,方法,构造函数

这里主要讨论 prototype,call,apply,Function

函数的prototype

每一个函数包涵一个prototype属性,这个属性是指向一个对象的引用,这个对象称为“原型对象”(prototype object)。当函数用作构造函数调用时,新创建的对象会从原型对象(__proto__)上面继承属性。

所以prototype是在描述,当function实例化以后需要继承哪个对象的属性,而且这个被继承的属性将被实例化对象中的属性 __proto__引用。

就是说prototype是描述继承关系,实质上对象继承的继承 靠 __proto__ 属性来实现。
当然 prototype 是函数的属性,而__proto__ 是对象的属性

var animal= function(){
    this.eat = function(){
        console.lof('i can eat')
    }
}
var cat = function(){
    this.sleep = function(){
    console.log('i can sleep')
    }
}
cat.prototype = new animal()
var my_cat = new cat();

my_cat.eat() //  ===> i can eat
my_cat.sleep()  // ===> i can sleep

我们可以看看 my_cat 对象中的属性:

这里写图片描述

my_cat.prototype ==== > undefined
my_cat.\__proto__  ==== > animal 对象
my_cat.\__proto__.constructor == function animal ....   

注意:不要试图修改实例化对象的 __proto__ 。
1. 并不是所有平台都支持__proto__属性,修改会带来兼容性问题;
2. 大部分平台都会对原型对象的索引进行优化,修改会破坏原有的原型链,这会影响性能;
3. 原型对象是公用对象,修改该对象会影响其他继承该对象的 对象
4. 替换对象这会影响整个继承层次的结构

方法 call、apply

call&apply 这个两个是 function的属性,继承Function.prototype;

这两个属性的效果一个,只是传入参数不一样。

这两个方法常用于方法的复用,和对象继承;

继承

var animal = function(){
    this.eat = function(){
        console.log('eat')
    }
}

var cat = function(){
    animal.call(this) // animal.apply(this)
    this.sleep = function(){
        console.log('sleep')
    }

var cat_case = new cat();
cat_case.eat() // ===> eat
cat_case.sleep() // ===> sleep

复用

alert(Math.max(5,7,9,3,1,6));   //9   

//但是在很多情况下,我们需要找出数组中最大的元素。   

var arr=[5,7,9,1];  
//alert(Math.max(arr));    // 这样却是不行的。NaN   

//要这样写   
function getMax(arr){  
    var arrLen=arr.length;  
    for(var i=0,ret=arr[0];i<arrLen;i++){  
        ret=Math.max(ret,arr[i]);  
    }  
    return ret;  
}  

alert(getMax(arr)); //9   

//换用apply,可以这样写   
function getMax2(arr){  
    return Math.max.apply(null,arr);  
}  

alert(getMax2(arr)); //9   

//两段代码达到了同样的目的,但是getMax2却优雅,高效,简洁得多。   

bind方法

这里的bind 方法讨论ES3 兼容。从名字就能看出,这个方法主要作用就是将函数绑定至某个对象。当函数f()上调用bind()方法并传入一个对象o座位参数,这个方法将返回一个新的函数。调用新的函数将会把原始的函数f( )当做o的方法来调用。传入新函数的任何实参都将传入原始函数,如:

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

bind除了绑定一个函数至对象上,他还附带一些其他应用:除了第一个实参以外,传入bind的实参都会绑定至this,这个附带的应用是一种比常见的编程技术,有时也被称为‘柯里化’。下列例子就是柯里化的例子

var sum = function(x,y){return x + y} 

var succ = sum.bind(null,1);
succ(2) // ==> 3

function f(y,z){return this.x + y + z }
var g = f.bind({x:1},2)
g(3) // ⇒ 6 

Function 构造函数

本文开头说过,function是Function的实例化对象,也就是说,我们可以通过 new 关键字来 实例化一个函数:

var f = new Function('x','y','return x+ y')

这几乎等价于

var f = function(x,y){ return x + y }

不建议使用这种方式 定义函数

参考:
《JavaScript权威指南》 作者:David Flanagan
《Effective JavaScript》 作者: David Herman

猜你喜欢

转载自blog.csdn.net/hulk_oh/article/details/52839433