IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> 详解 this -> 正文阅读

[游戏开发]详解 this

this 指向

如果我们将环境传入
function foo(context) {
    return context.toUpperCase();
}
function bar(context) {
    return context + '欢迎';
}
foo(环境1);
bar(环境2);


我们使用 this
function foo(context) {
    return this.toUpperCase();
}
function bar(context) {
    return this + '欢迎';
}
foo.call(环境1);
bar.call(环境2);
  1. this 可以对多个环境对象进行复用, 不用针对每个环节对象做各自的版本。

  2. this 以更加优雅的方式来隐含的传递一个引用,更加干净的API设计和更容易的复用。

怎么样来确定 this

this 是根据调用点(函数如何被调用的)而为每次函数调用建立的绑定, 它是影响 this 绑定的唯一因素。

默认绑定

当函数是独立调用的,也就是函数前面没有任何的调用条件。

function foo() {
    console.log(this);
}

foo();  // 独立调用


或者是
function foo() {
    setTimeout(function => {
        console.log(this);  // 独立调用
    }, 1000);
}

所以上面情况应用到默认绑定,在非严格模式下,this指向全局的 window,在严格模式下,this 是 undefined.

隐式绑定

当函数的调用点是一个环境对象,那么这个时候函数的this会指向这个对象。

var obj = {
    fn: function () {console.log(this);}
}
obj.fn();  // 隐式绑定 obj


或者是
function foo() {console.log(this);}
var obj = {
    fn: foo
}

obj.fn();  // 隐式绑定 obj

虽然第二种情况的 foo 函数不是一开始就在 obj 身上,后来作为引用添加到了 obj 身上,不能说是 obj 有了这个函数,而是当 fn 函数调用的时候,才能说 obj 真正的拥有了 foo 函数。

但是存在一个问题,这种隐式绑定容易丢失。

var obj = {
    fn: function () {console.log(this);}
}

var fn = obj.fn;
fn();  // 丢失了绑定 ---> 默认绑定 window


或者是
var obj = {
    fn: function () {console.log(this);}
}

setTimeout(obj.fn, 1000);  // 丢失了绑定 ---> 默认绑定 window

这种情况下, 通过赋值 fn = obj.fn 知识把 fn 函数的地址给了 fn 变量,虽然二者引用到了一块内存区域,但是调用的时候 fn 是没有绑定规则的。

明确绑定

如上面的,我们不得不改变目标对象使得它自身包含一个对象引用。然后来间接的调用这个函数,改变调用点。
如果你想要强制一个函数使用某个特定对象作为 this 绑定的话,就需要借助 apply,call 了。

function foo() {console.log(this);}
var obj = {};
或者 foo.call(obj);
或者 foo.apply(obj);

这样就可以使得 foo 调用的时候, 就可以我们自己来制定它的 this 是谁。比起需要一个专门的对象环境对象来作为它的 this 好简单的多。

apply、call 存在的问题。它们依然不能够上面的绑定丢失问题。而且它们是一次性绑定。

一次性绑定
function foo() {console.log(this);}
var obj = {};
foo.call(obj); // obj 好使
foo(); // window 又回去了

我们自己写的函数我们可以控制,但是对于别人的函数我们就不能够控制 this 绑定了
function foo() {console.log(this)}  // obj 好使
var obj = {};
function myFun(fn) {console.log('我的函数', fn.call(obj))}
myFunc(foo);


别人的代码, 那么我们就不能够进入到内部去改变指向了
function foo() {console.log(this);}  // 不好使 window
var obj = {};
setTimeout(foo, 1000);

硬绑定

看上面代码,我们发现 call, apply 存在不是一次性绑定,不能解决 this 丢失问题, 硬绑定是一次性的绑定,并且可以解决 this 指向丢失问题。

一次性问题
function foo() {console.log(this);}
var obj = {};

var bar = foo.bind(obj);
bar();  // 好使 obj
bar();  // 好使 obj

丢失问题
function foo() {console.log(this);}
var obj = {};

setTimeout(foo.bind(obj), 1000); // 好使 obj

解决了,我们可以理解为,通过 foo.bind 包装了一个绑定到 obj 的函数,然后传入到定时器。

new 绑定

使用 new 来初始化一个类时,这个类的构造器就会被调用。

function Person(name) {
    this.name = name;  // person
}

var person = new Person('xx');

我们使用 new 来执行构造器,构造器的 this 会绑定为 person 这个对象。往 person 上添加 name 属性。

这么多绑定,总要有一个优先级排序吧(覆盖)

  1. 不用说肯定是 默认绑定 最低了吧,毕竟没有人罩着。
  2. 隐式绑定 obj.foo 方式。
  3. 明确绑定
function foo() {console.log(this);}
var obj1 = {fn: foo}
var obj2 = {fn: foo}
obj.fn.call(obj2);  // obj2 没错了, 明确绑定确实比隐式绑定要强
  1. 硬绑定
function foo() {console.log(this.name);}
var obj1 = {fn: foo, name: 'obj1'};
var obj2 = {fn: foo, name: 'obj2'};
foo.bind(obj2).call(obj1);  // 好使 'obj2' 说明硬绑定要高于明确绑定
  1. new 绑定
function Person() {console.log(this)}
var obj = {};
var Person1 = Person.bind(obj);
var person = new Person1();  // 好使 person  new绑定要高于硬绑定

这主要是因为在 bind 源码中是: this instanceof fNOP ? this : oThis; 如果是 函数的话,就会返回这个 new 出来的对象,否则才是 bind 绑定的对象。 (要想了解,看 bind 章节)。

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:54:07  更:2022-03-08 22:54:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 17:56:32-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码