浏览器工作原理学习(十)

news/2024/7/4 7:14:55

this

  • 在对象内部的方法中使用对象内部的属性是一个非常普遍的需求。但JS的作用域机制并不支持这一点,为此,JS高出了this机制。
  • this 和作用域链是2套不同的系统。
  1. 什么是this?
  • this是和执行上下文绑定的, 每个执行上下文中都有一个this。
  • 分三种类型:全局执行上下文中的this,函数中的this,eval中的this。
  • 全局执行上下文中的this是指向window对象的,这是this合作用域链唯一的交点,作用域链的最底端包含了window对象,全局执行上下文中的this也是指向window对象。
  • 函数执行上下文中的this:默认情况下调用一个函数,其执行上下文也是指向window对象。
  • this 永远指向最后调用它的那个对象。
  1. 设置this指向方法
  • 使用箭头函数:箭头函数的this始终指向函数定义时的this,而非指向时。箭头函数没有this绑定,必须通过查找作用域链来决定值,如果箭头函数被非箭头函数包含,则this绑定的时最近一层非箭头函数的this,否者,this为undefined。
  • 在函数内部使用_this=this:将被调用的函数对象保存到变量_this变量中。
  • 使用call、apply、bind改变this的指向。
/*
 call()方法调有一个指定得this值和一个参数列表,参数1:thisArg可选。参数2:arg,arg2...返回值:使用调用者提  供的this值和参数调用该函数的返回值。
*/
	Function.prototype.defineCall=function(ctx,...args){
		if(!ctx){
			ctx= typeof window !=='undefined'?window:global
		}
		ctx = Object(ctx)
		const fnName = Symbol()
		ctx[fnName] = this
		const result = ctx[fnName](...args)
		delete ctx[fnName]
		return result
	}
	let fn = function(name,sex){
    	console.log(this,name,sex)
    }
    fn.call('','测试1') // window 测试1
    fn.call({name:'测试1',sex:'boy'},'测试2') // {name:'测试1',sex:'boy'}
    
/*
  apply()方法调用一个具有给定的this值得函数,以及一个参数数组。参数1:thisArg必选,参数2:argsArray可选 
 返回值:调用有this值和参数得函数得结果。  
*/ 
	Function.prototype.defineApply = function(ctx,args){
		if(!ctx){
			ctx = typeof window !== 'undefined'?window:global
		}
		ctx =Object(ctx)
		const fnName = Symbol()
		ctx[fnName]= this
		// 将args参数数组,展开为多个参数,供函数调用
		const result = ctx[fnName](...args)
		delete ctx[fnName]
		return result
	}
    let fn = function(name,sex){
		console.log(this,name,sex)
	}
	fn.defineApply('',['测试2','boy']) // window 测试2 boy
	fn.defineApply({name:'测试2',sex:'boy'},['测试2','boy']) //  {name:'测试1',sex:'boy'} ['测试2','boy']
 
 /*
 bind()方法创建一个新的函数,在bind被调用时,这个新函数的this被指定为bind第一个参数,而其余参数作为新函数的参数,供调用时借用。
*/ 
   Function.prototype.defineBind= function (context, ...args) {
    const fn = this
    args = args ? args : []
    return function newFn(...newFnArgs) {
        if (this instanceof newFn) {
            return new fn(...args, ...newFnArgs)
        }
        return fn.apply(context, [...args,...newFnArgs])
    }
}
const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};
const unboundGetX = module.getX;
console.log(unboundGetX()); // undefined
const boundGetX = unboundGetX.defineBind(module);
console.log(boundGetX()) // 42 
  • 通过对象调用的方法设置:使用对象来调用其内部的一个方法,该方法的this是指向对象的。
  • 通过构造函数设置
  function CreateTest(){
	this.name='测似1'
 }
 var testName = new CreateTest()

http://www.niftyadmin.cn/n/2608627.html

相关文章

linux下不同服务器间数据传输(rcp,scp,rsync,ftp,sftp,lftp,wget,curl)

rcp rcp不是一种安全的的传输文件的方式,rcp通过rsh(rsh见下面)来执行远程命令,要使用rcp必须经过一些配置,现在rcp已经被scp取代了,常用scp来进行文件传输。要使用rcp,需要具备以下条件&#x…

浏览器工作原理学习(十一)

语言类型 在使用前需要确认其变量数据类型的称为静态语言©,运行过程中需要检查数据类型的语言称为动态语言(js)。在赋值时,语言回进程隐式类型转换,这类语言被称为弱类型语言,不支持隐式类型转换额语言称为强类型语言。 JS数…

【跃迁之路】【423天】刻意练习系列182—SQL(2018.04.04)

(跃迁之路)专栏 叨叨两句 技术的精进不能只是简单的刷题,而应该是不断的“刻意”练习该系列改版后正式纳入【跃迁之路】专栏,持续更新刻意练习——MySQL 2018.04.02 题目描述 DROP TABLE IF EXISTS test1;CREATE TABLE test1 (id int(11) NOT NULL AUTO_…

浏览器工作原理学习(十二)

编译器和解释器 按语言的执行流程,可以把语言划分为编译型语言和解释型语言。编译型语言:在程序执行前,需要经过编译器的编译过程,并且编译之后会直接保留机器能读懂的二进制文件,这样每次运行程序时,都可以…

离线计算成本节省的神兵利器

摘要: 对于创业成长型的企业来说,离线计算已经必不可少了,通过离线计算我们可以生成复杂的业务报表,通过离线计算我们也能精确的算出用户画像。离线计算已经当今的企业中成为了不可或缺的存在。那么使用弹性计算能够对离线计算领域…

浏览器工作原理学习(十三)

消息队列和事件循环系统 消息队列 消息队列是一种数据结构,可以存放要执行的任务。它符合队列先进先出的特点。IO线程中的产生的新任务会添加进消息队列尾部。渲染主线程会循环地从消息队列头部中读取任务,执行任务。由于多个线程操作同一个消息队列&am…

浏览器工作原理学习(十四)

WebAPI:setTimeout 浏览器中的setTimeout 执行一段异步任务,需要先将任务添加到消息队列中。为了保证回调函数能在指定时间内执行,定时任务的回调函数不能直接添加到消息队列。延迟队列:维护消息队列中需要延迟执行的任务列表。如果当前任务…

(牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)

假定一种编码的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a, aa, aaa,aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx,yyyy 其中a的Index为0&…