资讯专栏INFORMATION COLUMN

深入挖掘js之函数

douzifly / 2549人阅读

摘要:通过可取可取的他们所属对象的上下文的方法称为公共方法函数调用模式当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的,以此模式调用函数,被绑定到了全局对象。

前言: 前端这两年的新技术铺天盖地,各种框架、工具层出不穷眼花缭乱。最近打算好好复习下 js 基础,夯实的基础才是学习新技术的基石。本文作为读书笔记简单的总结下 js 函数的基础知识。

一、函数对象

JavaScript中的函数就是对象。对象是“名/值”对的集合并拥有一个连接到原型对象的隐藏连接。对象字面量产生的对象连接到Object.prototype。函数对象连接到Function.prototype(该原型对象本身连接到Object.prototype)。

每个函数对象在创建时也会有一个prototype属性。它的值是一个拥有constructor属性且值即为该函数的对象。

函数是对象,可以保存在变量、对象和数组中。函数可以当做参数传递给其他函数,函数也可以在返回函数,函数拥有方法。

二、函数字面量

函数对象通过函数字面量来创建:

var add = function(a,b){
return a+b;
};

函数字面量包括四个部分:

1 保留字function

2 函数名(可省略)

3 包围在括号中的一组参数,在函数被调用是初始化为实际的参数的值

4 包围在花括号里的一组语句块

注意:一个内部函数除了可以访问自己的参数和变量,同时也可以自由的访问父函数的参数和变量。用过这种函数字面量创建的函数对象包含一个连接到外部上下文的连接。这个被称为闭包

三、函数调用

每个函数接收两个附加的参数:this和arguments(实际参数),在JavaScript中有四种调用方式:方法调用模式,函数调用模式,构造器调用模式和apply调用模式

方法调用模式

当有个函数被保存为对象的一个属性是,我们称他为一个方法。当以个方法被调用时,this被绑定到该对像。

 var myObject = {
    value: 0,
    increment: function (icn) {
        this.value += typeof inc === "number" ? icn: 1;
    }
}
myObject.increment();
console.log(myObject.value);

myObject.increment(2);
console.log(myObject.value);

方法可以使用this访问自己所属的对象。通过this可取可取的他们所属对象的上下文的方法称为公共方法

函数调用模式

当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的,以此模式调用函数,this被绑定到了全局对象。这是错误的,正确的设计应该是当内部函数被调用时,this应该绑定到外部函数的this变量。因此声明一个that变量并赋值this,内部函数就可以通过that访问到this。这个听起来比较难理解,我们以代码的形式来说明

myObject.double = function(){
    var that = this ;
    var helper = function(){
        that .value = add(that.value,that.value);
    }
    helper(); //以函数的形式调用helper
}
//以方法的形式调用double
myObject.double();
console.log(myObject.value);
构造器调用模式

JavaScript是基于原型继承的语言,对象可以直接从其他对象继属性,该语言是无类型的。

如果在一个函数前面带上new来调用,name背地里就会创建一个连接到该函数的prototype成员的新对象,同时this会绑定到新对象上

//创建一个构造器函数Quo
var Quo = function(string){
    this.status = string;
};
//给Quo提供一个get_status的公共方法
Quo.prototype.get_status = function(){
    return this.status;
};
//构造一个Quo实例
var myQuo = new Quo("hello world");
console.log(myQuo.get_status());
Apply 调用模式

apply方法可以构建一个参数数组传递给调用函数,apply方法接收两个数组,第一个是要绑定给this的值,第二个就是一个参数数组。

var array = [3,4];
var sum = add.apply(null,array);
var statusObject = {
    status: "A-ok"
};
 var status = Quo.prototype.get_status.apply(statusObject);
 console.log(status); //A-OK
参数

当函数被调用时会得到arguments数组,函数可以通过此参数访问所有被它调用时传递的参数列表

arguments并不是一个真正的数组,拥有一个length属性,但它没有任何数组的方法
返回

如果函数调用时在前面加一个new前缀,且返回值不是一个对象,则返回this

四、函数作用域

我们已经知道,在代码外部添加包装函数将内部的变量和函数定义“隐藏”起来,外部作用域无法访问包装函数内部的任何东西 例如:

var a = 2;
function foo(){
var a =3;
consloe.log(a);//3
}
foo();
consloe.log(a);//2
闭包

内部函数可以访问定义在他们外部的函数的变量和参数(除了this、arguments)

var que = function(status){
    return {
        get_status: function(){
            return status;
        }
    }
}
var myQuo = que("hello");
console.log(myQuo.get_status());

get_status方法并不是访问参数的副本,他访问的就是参数的本身,这就是闭包,保护status为私有属性

回调callBack()

1 搞清异步和同步

function a(){
    console.log("执行a函数");
    setTimeout(function(){
        console.log("执性a函数的延迟函数")
    },1000)
};
function b (){
    console.log("执行函数b")
}
a();
b();

以上代码会先执行函数a,而且不会等到a中的延迟函数执行完才执行函数b, 在延迟函数被触发的过程中就执行了函数b,当js引擎的event 队列空闲时才会去执行队列里等待的setTimeout的回调函数,这就是一个异步的例子

2回调函数到底是什么

以下是谷歌得出的结论

callback is a function that is passed as an argument to another function and is executed after its parent function has completed.
模块

我们可以使用函数和闭包来构造模块,模块是一个提供个借口却隐藏状态与实现的函数或对象

模块模式利用函数作用域和闭包来创建被绑定对象与私有成员的关联

模块的一般形式:一个定义了私有变量和函数的函数;利用闭包创建可以访问私有变量和函数的特权,最后一个返回该特权函数,或者把它们保存在一个可以访问的到的地方

模块模式需要具备两个条件

1、必须有外部的封装函数,该函数必须至少被调用一次(每次调用都会创建一个新的模块实例)。

2、封闭函数必须返回至少一个尼日不函数,这样内部函数才能在私有的作用域形成闭包,并且可以访问或者可以修改私有状态。

var foo= (function(){
    var something = "cool";
    var another =[1,2,3];
    function doSomething(){
        console.log(something);
    }
    function doAnother(){
        console.log(another.join(" ! "));
    }
    return{
        doSomething: doSomething,
        doAnother: doAnother
    }
})();
foo.doSomething();
foo.doAnother();

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/107688.html

相关文章

  • 深入挖掘js继承

    摘要:一伪类当一个函数对象被创建时,构造器产生的函数对象会运行类似这样的代码新函数对象被赋予了一个属性,他的值是一个包含属性且属性值为该新函数的对象。这个对象是存放继承特征的地方。 一、伪类 当一个函数对象被创建时,Function构造器产生的函数对象会运行类似这样的代码: this.prototype = { constructor: this}; 新函数对象被赋予了一个prototype...

    zxhaaa 评论0 收藏0
  • 深入挖掘js作用域闭包

    摘要:前提中闭包无处不在,你只需要能够识别并拥有它。一实质问题当函数可以记住并访问所在的词法作用域是,就产生了闭包。依然持有该作用域的引用。延迟函数的回调会在循环结束时才执行。每个延迟函数都会讲在每次迭代中创建的作用域封闭起来。 前提:JavaScript中闭包无处不在,你只需要能够识别并拥有它。闭包是基于词法作用域书写代码时自然产生的结果。 一、实质问题 当函数可以记住并访问所在的词法作用...

    xiangchaobin 评论0 收藏0
  • 深入挖掘js数组

    摘要:对象字面量数组运行数组包括任意混合类型的数组。属性的值是这些数组的最大整数属性名加上。它等于数组里的属性的个数。可以使用向数组中增加元素,也可以用方式加入到数组中。六指定初始值数组通常不会预置顶。 一、数组字面量 数组字面量提供了一种非常方便的创建数组的表达法。 一个数组字面量是在一对方括号中包围零个或多个用逗号分隔的值的表达式。 对象字面量数组: var numbers_obje...

    shleyZ 评论0 收藏0
  • 深入理解JavaScript

    摘要:深入之继承的多种方式和优缺点深入系列第十五篇,讲解各种继承方式和优缺点。对于解释型语言例如来说,通过词法分析语法分析语法树,就可以开始解释执行了。 JavaScript深入之继承的多种方式和优缺点 JavaScript深入系列第十五篇,讲解JavaScript各种继承方式和优缺点。 写在前面 本文讲解JavaScript各种继承方式和优缺点。 但是注意: 这篇文章更像是笔记,哎,再让我...

    myeveryheart 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<