理解new构造函数和apply以及call
今天在看设计模式的时候,遇到一些挺低级的东西,搞不懂,顾查阅资料整理记录一番。
先了解一下new构造函数的过程:
function func(){
console.log('do');
}
var foo = new func();
1、创建一个foo的空对象;
2、将func内部的this指向foo函数;(继承func函数内部的属性和方法)
3、foo._proto_ = func.prototye;(继承func的原型方法)
4、执行一遍foo,为其初始化;
5、返回一个foo对象;
(2018/04/17)补充:
1.创建一个foo空对象
2.foo._proto_ = func.prototype;
3.func.call(foo);
4.return foo;
二、call和apply的内部方法原理是一样的,只是使用方法不同。
先来一段官方定义:call和apply用于更改函数的执行上下文环境。
其实这样是很难理解的,到底什么意思呢?还是得上代码。
1)替换函数对象
function Cat() {
this.animal = 'cat';
console.log(this.animal);
}
function Dog() {
this.animal = 'dog';
}
Cat.call(Dog); //cat
内部执行可以分步骤进行:
1、Cat函数内部的this指向Dog函数;
2、执行Cat函数的函数上下文;
3、this.animal即为Dog.animal,因此Dog.animal赋值为‘cat’;
4、输出this.anmial即输出Dog.animal;
2)直接调用函数内部的方法
var func = {
txt : 'text',
showTxt : function() {
console.log(this.txt);
}
}
var foo = {
txt : 'document'
}
func.showTxt.call(foo); // document
步骤与例1差不多:
1、func的this指向foo;
2、执行func函数;
3、执行foo.showTxt函数;由于showTxt此时的调用者为foo,因此,showTxt内部的this指向foo,所以foo.txt为document;
此外,也有另一种请况:
function func() {
this.txt = 'text';
this.showTxt = function() {
console.log(this.txt);
}
}
function foo(){
this.txt = 'document';
}
func.showTxt.call(foo); // TypeError
这里会报错为TypeError,原因为并没有为foo对象进行初始化,只是执行了func的执行上下文。
如果是这样:
function func() {
this.txt = 'text';
this.showTxt = function() {
console.log(this.txt);
}
}
function foo(){
this.txt = 'document';
}
var m = new func();
var n = new foo();
m.showTxt.call(n); // document
外部函数的内部函数的调用必须经过初始化。
3)函数继承
function func(){
this.showName = function(){
console.log(1111);
}
}
function foo(){
func.call(this);
}
var son = new foo();
son.showName();//1111
理解了上面两个例子就容易理解了。
(2018/04/17)补充:
关于call和apply存在的意义:
var func1 ={
name : "jhon";
say : function() {
console.log(this.name)
}
}
obj = {name:"lili"};
func1.say.call(obj); // lili (注意:call和apply方法只能作用于Object对象上,Function上是不存在的)
理解new构造函数和apply以及call的更多相关文章
- 理解Angular中的$apply()以及$digest()
$apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...
- 深入理解js构造函数
JavaScript对象的创建方式 在JavaScript中,创建对象的方式包括两种:对象字面量和使用new表达式.对象字面量是一种灵活方便的书写方式,例如: ? 1 2 3 4 5 6 var o1 ...
- 深入理解Angular中的$Apply()以及$Digest()
$apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$apply()和$digest()是如何工作的 ...
- 通俗理解angularjs中的$apply,$digest,$watch
<!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <me ...
- JS中面向对象的,对象理解、构造函数、原型、原型链
6.1 理解对象 6.1.1 对象属性类型 ECMS属性有两种类型:数据属性和访问器属性 1 数据属性 [[configurable]] 表示能否通过Delete 删除属性从而从新定义属性,能否修改属 ...
- 深入理解javascript构造函数和原型对象
---恢复内容开始--- 对象,是javascript中非常重要的一个梗,是否能透彻的理解它直接关系到你对整个javascript体系的基础理解,说白了,javascript就是一群对象在搅..(哔! ...
- (网页)理解Angular中的$apply()以及$digest()
转自CSDN: 工作有问题上CSDN上转转. $apply()和$digest()在AngularJS中是两个核心概念,但是有时候它们又让人困惑.而为了了解AngularJS的工作方式,首先需要了解$ ...
- (转) 理解Angular中的$apply()以及$digest()
原文地址:http://blog.csdn.net/dm_vincent/article/details/38705099 $apply()和$digest()在AngularJS中是两个核心概念,但 ...
- 深入理解Thread构造函数
上一篇快速认识线程 本文参考汪文君著:Java高并发编程详解. 1.线程的命名 在构造现成的时候可以为线程起一个名字.但是我们如果不给线程起名字,那线程会有一个怎样的命名呢? 这里我们看一下Threa ...
随机推荐
- 01.redis初识
Redis学习: redis是什么? Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 不过Redis在生产环境中使用最多的功能是缓存系统.至于其 ...
- 离开Visual Studio C#的编译(你不知道的C#)
很多人一开始学习.net 第一天必定是安装Visual studio 或者很多关于C#学习的书上第一章节必定是告诉你要你下载一个vs 其实没有vs未必就不能开发了,只是可能说vs给我的开发带来了很多的 ...
- session与cookie的区别与联系
session与cookie是在做项目中很常用的会话技术,session与cookie也是面试中被问到频率最高的问题,有一次我去面试,面试官就怼着我session与cookie一直问(头都大了),下面 ...
- Web前端学习——HTML
HTML其实还是蛮容易学习的,无非就是一些标签.格式的填写,大学的时候也做过网站设计,所以这里主要记录一些常用的HTML标签.属性以及书写方法等. 一.常见HTML格式 主要包含文件type,html ...
- 【技能大赛笔记01】Zigbee点对点按键控制程序开发
[技能大赛笔记01]Zigbee点对点按键控制程序开发 --2017年"物联网物联网技术应用与维护"任务五题1(中职组) 1.题目要求 2.工程文件 在比赛中,提供了一个基于Bas ...
- iOS开发之线程间的MachPort通信与子线程中的Notification转发
如题,今天的博客我们就来记录一下iOS开发中使用MachPort来实现线程间的通信,然后使用该知识点来转发子线程中所发出的Notification.简单的说,MachPort的工作方式其实是将NSMa ...
- 关于Mysql下使用Dapper QueryFirstOrDefault的问题
1.环境 MySql:5.7.20 Dapper:1.50.2 .Net:4.5 2.遇到的问题 在开发中我发现,使用Dapper查询数据时,第一次查询正确,第二次查询就差不出来,或者直接修改数据库后 ...
- loadrunner 参数存储在data.ws、paralist、globals.h 中区别(参数与变量额区别于使用)
1.如果变量数据只有一个值,可以直接放在data.ws 中 2.如果变量要根据循环取随机值.序列值等(参数存在一组值),放在paralist中 3.如果是申明全局变量,且要在代码中用到参 ...
- Java 封装 HDFS API 操作
代码下载地址:点击下载 一:环境介绍 hadoop:2.6 Ubuntu:15.10 eclipse:3.8.1 二:操作包含 推断某个目录是否存在 isExist(fold ...
- Javascript 进阶 面向对象编程 继承的一个样例
Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承.这篇使用一个样例来展示js怎样面向对象编程.以及怎样基于类实现继承. 1. ...