每日一题(二二)var fullname = 'a'; var obj = { fullname: 'b', prop : { fullname: 'c'

本文深入解析JavaScript中this关键字的指向规则,通过具体示例代码解释不同调用方式下this指向的变化,包括作为对象属性调用、全局作用域下直接调用、使用new关键字调用以及使用call、apply、bind强绑定调用。

题目描述:写出执行结果并解释原因

var fullname = 'a';
var obj = {
    fullname: 'b',
    prop : {
        fullname: 'c',
        getFullname: function(){
            return this.fullname;
        }
    }
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());

答案:

c
a

解析:

  • 原因在于 this 指向的是函数的执行环境, this 取决于其被谁以哪种方式调用了,而不是被谁定义了。
  • 对第一个 obj.prop.getFullname() 而言,getFullname() 是作为 obj.prop 对象的一个方法调用的,因此此时的执行环境应该是这个对象。
  • obj.prop.getFullname 被分配给 test 变量时,此时的执行环境变成了全局对象(window),原因是 test 是在全局作用域下定义的。因此,此时 this 指向的是全局作用域的 fullname 变量,即 a

this 指向取决于函数被谁以何种方式调用的,一般分为四种方式

  • 被当作对象的属性调用,this 指向调用对象,例如上面的 obj.prop.getFullname()
  • 在全局作用域下直接调用,即 fn(),例如上面 test = obj.prop.getFullname; test()。这里 test 就是直接调用。
  • 使用 new 关键字调用,this 指向新生成的实例对象
  • 使用 call、apply、bind 强绑定调用,this 指向绑定对象
### 错误原因 当遇到 `Uncaught (in promise) TypeError: 'set' on proxy: trap returned falsish for property` 的错误时,通常是因为在设置代理对象的某个属性时,`Proxy` 的 `set` 捕获器(trap)返回了一个假值(falsy)。这表明捕获器阻止了该操作的成功完成。 对于不同场景下的具体表现: - 当尝试给特定属性赋值时触发验证逻辑失败[^2]。 - 变量定义位置不当导致计算属性无法正确更新[^3]。 - 计算属性中的 setter 方法未能成功处理传入的新值[^4]。 ### 解决方案 #### 场景一:属性验证未通过 如果是在执行某些验证规则的情况下抛出了此异常,则需确保所有可能的情况都得到了妥善处理。例如,在年龄验证的例子中,应该覆盖所有的边界情况并提供默认行为来防止意外中断程序流程。 ```javascript let validator = { set: function(obj, prop, value) { try { if (prop === 'age') { if (!Number.isInteger(value)) { console.warn('The age should be an integer'); return false; } if (value > 200 || value < 0) { console.warn('The age seems invalid'); return false; } } obj[prop] = value; return true; // 明确返回true表示允许修改 } catch (e) { console.error(e); return false; } } }; ``` #### 场景二:组件内部状态管理问题 针对Vue框架内可能出现的问题,特别是涉及模板编译期间的状态初始化顺序或响应式绑定机制引发的冲突,应调整声明语句的位置以确保依赖关系被正确定义和解析。 ```typescript // 正确做法 const props = defineProps<{ visible: boolean }>(); const state = reactive({ form: { name: '' }, formLabelWidth: '100px' }); // 将visible作为独立变量而不是state的一部分 const visible = computed(() => props.visible); // 使用toRefs解构其他不需要特别处理的数据项 const { form, formLabelWidth } = toRefs(state); ``` #### 场景三:计算属性setter实现缺陷 最后一种常见情形是由于计算属性的 getter/setter 实现存在漏洞所引起的。为了修复这个问题,可以简化逻辑结构或者增加必要的输入校验措施。 ```javascript import { reactive, computed } from "vue"; let person = reactive({ xing: '', ming: '' }); person.fullname = computed({ get: () => `${person.xing}-${person.ming}`, set(newValue) { if(typeof newValue !== 'string'){ console.log("Invalid input type"); return false; } let parts = newValue.split('-'); if(parts.length != 2){ console.log("Incorrect format of full name"); return false; } person.xing = parts[0]; person.ming = parts[1]; return true; } }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值