js中的4种函数调用模式

javascript一共有4种调用模式:函数调用模式、方法调用模式、构造器调用模式和间接调用模式。

【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 } add();

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

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

重写

因为函数调用模式的函数中的this绑定到全局对象,所以会发生全局属性被重写的现象

  

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

当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,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

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

  如果构造函数没有形参,javascript构造函数调用的语法是允许省略实参列表和圆括号的。凡是没有形参的构造函数调用都可以省略圆括号

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】间接调用模式

  javascript中函数也是对象,函数对象也可以包含方法。call()和apply()方法可以用来间接地调用函数

  这两个方法都允许显式指定调用所需的this值,也就是说,任何函数可以作为任何对象的方法来调用,哪怕这个函数不是那个对象的方法。两个方法都可以指定调用的实参。call()方法使用它自有的实参列表作为函数的实参,apply()方法则要求以数组的形式传入参数

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

原文地址:https://www.cnblogs.com/limengyao/p/9445103.html

时间: 2024-10-10 03:33:08

js中的4种函数调用模式的相关文章

Activity中的四种启动模式

在Android中每个界面都是一个Activity,切换界面操作其实是多个不同Activity之间的实例化操作.在Android中Activity的启动模式决定了Activity的启动运行方式. Android总Activity的启动模式分为四种: [html] view plaincopy Activity启动模式设置: <activity android:name=".MainActivity" android:launchMode="standard" 

.Net中的几种异步模式

.Net中的几种异步模式 .Net中的几种异步模式基于事件的异步模式(EAP)IAsyncResult接口简单的异步模式--引入lambdaTask手动异步编程的问题 在C# 5.0引入async之前,存在几种异步编程模式,比如Event-based Asynchronous Pattern.IAsyncResult接口.Task等等. 基于事件的异步模式(EAP) private void DumpWebPage(Uri uri) { WebClient webClient = new Web

谈谈 js中的几种模式 (一)

今天看了<JavaScript 高级程序设计>(第三版)这本书,颇有收获,总想写点什么,只恨自己菜鸟一只写不出什么真知灼见,只能......好了废话不多说,开篇了. 大家都知道在js中可以用Object构造函数和对象字面量这 //利用Object构造函数创建对象 var person=new Object(); person.name="DJL"; person.age=22; //利用对象字面量创建对象 var person2={ name:"DJL"

js 四种函数调用模式

看js语言精粹,还在慢慢啃,啃到了一些之前没想到过的就在博客上记录一下吧.号外一下,工作室的汉子有时候太他妈没有节操了!!你们没节操就算了,当着我的面,这都什么鬼(崩溃中),不说这些没用的,进入正题吧. 调用一个函数会暂停当前函数的执行,传递控制权和参数给新函数.那么新函数会有哪些个参数呢,这就涉及到上节闭包里讲到的活动对象了,每个函数除了声明时定义的形参,还有两个this,arguments.this是个灰常重要的参数咯,它的值取决于调用的模式.在js中一共有4中调用模式:方法调用模式,函数调

javascript this 关键字以及四种函数调用模式

最近在学习javascript ,被js中的this关键字搞得晕头转向,都不知道这个东西到底是干什么的,不同的地方所指的对象又不一样.在查询了很多的资料以后,终于有了一些眉目了. this的定义:在javascript中,上下文对象就是this指针,即被调用函数所处的环境,上下文对象的作用是一个函数内部引用调用它的对象本身. 上面就是javascript中this关键字的定义,单纯的理解来说还是很好理解的,但是真正到用的时候发现又是另外一回事了. 说到this的用法,就要谈到到this的作用域,

【js实例】js中的5种基本数据类型和9种操作符

js中的5中基本数据类型 js标识符 第一个字符必须为字母,下划线,或美元符 其他字符可以是字母,下划线,美元符,数字 js标识符区分大小写 标识符不能使关键字和保留字 关键字: break do instanceof typeof case else new var catch finally return void continue for switch while debugger function this with default if throw   delete in try  

JS中的几种函数

函数可以说是js中最具特色的地方,在这里我将分享一下有关函数的相关知识: 包装函数:        (function foo(){...})作为函数表达式意味着foo只能在...所代表的位置中被访问,外部作用域则不行 (function foo(){...})()        第一个()将函数变成表达式,第二个()执行了这个函数,这种模式代表立即执行函数表达式   包装函数的声明以(function...而不是function开始,函数会被当作函数表达式而不是一个标准的函数声明来处理    

Android Activity中的四种启动模式

Android总Activity的启动模式分为四种: <activity android:name=".MainActivity" android:launchMode="standard" /> [standard]    默认模式启动模式,每次激活Activity时都会创建Activity,并放入任务栈中. [singleTop]    如果在任务的栈顶正好存在该Activity的实例, 就重用该实例,否者就会创建新的实例并放入栈顶(即使栈中已经存在

JS中的两种数据类型以及实现引用类型的深拷贝

一.前言 我们知道,在JS中数据类型按照访问方式和存储方式的不同可分为基本类型和引用类型.基本类型基本类型有String.Boolean.Number,Undefined.Null,这些基本类型都是按值传递的,也称为值类型. 引用类型引用类型有对象.数组.函数,它们都是按引用访问的. 二.存储方式区别 基本类型和引用类型由于两者在内存中存储的方式不同,造成两者访问的方式也不同.其中,基本类型存储在内存的栈中,是按值访问:引用类型存储在内存的堆中,是按引用访问.可如下图所示: 当有 1 var n