首页 > 其他分享 >为什么要使用Object.prototype.hasOwnProperty.call()?

为什么要使用Object.prototype.hasOwnProperty.call()?

时间:2023-12-14 15:22:32浏览次数:34  
标签:函数 Object 原型 hasOwnProperty call prototype

翻译自:What’s the deal with Object.prototype.hasOwnProperty.call()?

你一定在他人的代码或者某个库中见过下面的代码:

Object.prototype.hasOwnProperty.call(objRef, 'propName');

现在我们来看下这段代码到底什么意思。

在弄清楚的过程中,我们会依次理解下面几件事:

  1. Object.prototype是什么?
  2. 一个对象在没有定义该函数,在对象的原型链中也没有定义该函数时,为什么可以借调使用该函数?
  3. 为什么我们在Objectprototype上调用hasOwnProperty,而不是直接在objRef实例本身上调用?

好吧,让我们开始吧。

1. Object.prototype

Prototypal inheritanceJavaScript最主要的特性之一,它允许对象从它的原型中继承方法和属性。你可以把原型当成一个模板。

让我们看个例子:

var obj = {name: 'aman'}
obj.hasOwnProperty(‘name’)  // returns true

正如你所见,我们并没有在obj上定义hasOwnProperty,但是我们可以成功调用它,这是怎么回事?

这是因为原型继承和原型链的机制起作用了,让我们继续深入。

当我们创建字面量对象obj时,它的原型(prototype)被设定为了Object.prototype,我们可以通过下面的代码验证:

Object.getPrototypeof(obj) === Object.prototype // returns true
obj.__proto__ === Object.prototype // returns true

[[Prototype]]表明了对象之间的继承关系,在我们的例子中,即objObject.prototype之间的关系。

原型链长这样:

// Prototype chain
obj —-> Object.prototype ——> null

因此当我们调用hasOwnProperty()方法时,编译器在obj上找不到该方法,就向上找(原型链上找),在Object.prototype上找到了该方法。

此外,我们可以通过Object.setPrototypeOf() 或者Object.create(),自己设定或者重新配置对象的原型。

看下这个例子:

var person = {name: 'peter'};
var PersonPrototype = {getName: function(){ return this.name; }}; 

// Setting person's prototype 
Object.setPrototypeOf(person, PersonPrototype);

// Trying to access getName() method will cause a prototype chain lookup (aka prototype delegation) 
// and finds it on PersonPrototype. 
person.getName(); // 'peter'

2. 函数借用

假如我们有一个函数和一个对象:

function sayHello() { console.log(`Greetings ${this.name}`) }
var a = {name: 'peter'};

我们怎样做才能让a调用函数sayHellow并且传入a的名字peter呢?我们并不想让a去实现函数sayHello,也不想让函数sayHellow出现在a的原型链上。

答案就是通过Function.prototype上的callapply方法。

JavaScript中,我们创建的每个函数都继承了Function.prototype,正如上面我们介绍的原型链一样,我们可以在所有函数对象上调用call方法。

call method 的语法如下:

// 'call' method is available on Function.prototype
func.call(objRef, ...args); 

第一个参数是想要借用这个函数的对象,后面跟着函数的剩下的参数列表。

因此,想要借用函数sayHellow,我们需要做的就是将a作为参数传入sayHellow.call方法:

sayHello.call(a); // Greetings peter 

3. Object.prototype.hasOwnProperty vs instance.hasOwnProperty

在对原型继承和函数借用进行了简单介绍后,是时候弄清楚为什么我们在Object.prototype上调用hasOwnProperty而不是在实例本身上调用了。

正如我们上面介绍的那样,我们可以自己配置对象的原型链,一种方式就是在创建对象实例的时候使用 Object.create()

// Object.create() accepts an argument which becomes
// the prototype for newly created object.
var a = Object.create(null); // Setting `null` as prototype for 'a'. 

// Adding a 'name' property on the instance
a.name = 'peter';

// Using `hasOwnProperty` method would cause an error
a.hasOwnProperty('name'); //

标签:函数,Object,原型,hasOwnProperty,call,prototype
From: https://www.cnblogs.com/lhjc/p/17901246.html

相关文章

  • 使用Apache POI 导入导出时出现You need to call a different part of POI to process
    问题复现在学习导出功能时使用HSSFWorkbook导出了一个xxx.xlsx格式的文件,然后用XSSFWorkbook的读取方式来拿文件去导入时出现了这个bug这是当时做导出测试代码Workbookwb=newHSSFWorkbook();CreationHelpercreationHelper=wb.getCreationHelper();Sheetsheet=wb.cr......
  • python 定义类的时候的 A(object) 和 A 区别是什么?
    在Python中,A(object)和A的区别涉及到类的继承和类的定义方式。继承的区别:A(object)表示A类继承自object类。这是在Python2中引入新式类的写法,是显式地继承自基类object。在Python3中,所有的类都隐式继承自object,因此这两者在大多数情况下是等效的。A表示......
  • uniapp开发——纯原生渲染nvue调用uni.makePhoneCall没反应的处理办法
    uni.makePhoneCall(OBJECT)|uni-app官网(dcloud.net.cn)正常情况下,manifest.json配置拨打电话的权限就可以了:配置权限后重新打包,真机运行应该就可以正常的拨打电话了。如果API没反应,那么可以试试下边这种不弹出询问框直接拨打电话的方法:callMobile(){letmobile......
  • 关于使用appium自动化启动app时报错【问题:AttributeError: ‘NoneType‘ object has n
    报错原因:安装了最新版的appium3.0.0和selenium的最新版本,导致版本冲突从而导致报错:AttributeError:'NoneType'objecthasnoattribute'to_capabilities'解决方案:卸载selenium和appium,下载低版本的appium【下载appium的同时会下载依赖selenium】 pipinstall......
  • react_hooks系列 useCallback,高阶函数memo
    react_hooks的useCallback,高阶函数memo一、概念和作用1、memo高阶函数:memo解决的是函数式组件的无效渲染问题,当函数式组件重新渲染时,会先判断数据是否发生了变化。相当于类组件的PureComponent(默认提供ShouldComponentUpdate)2、useCallback:1)、useCallback会返回一个函数的memoiz......
  • WSL更新失败(退出代码: 1603) - Error code: Wsl/CallMsi/E_ABORT
    Whathappened?WSL莫名其妙的更新了,完成更新以后莫名奇妙地启动不起来了。每次运行WSL的时候都会给我提示WSL正在完成升级...更新失败(退出代码:1603)。Errorcode:Wsl/CallMsi/E_ABORT抓耳挠腮找了半天,我甚至不管写了一半的代码和笔记,把WSL卸载后重装,结果居然无法启动......
  • Object---clone方法
     概述java.lang.Object#clone Byconvention,thereturnedobjectshouldbeobtainedbycalling{@codesuper.clone}.Ifaclassandallofitssuperclasses(except{@codeObject})obeythisconvention,itwillbethecasethat{@codex.clone().getClass()=......
  • AttributeError: 'NoneType' object has no attribute 'replace'
    在python中执行Js代码,引入execjs库,python代码如下:执行结果如下:在导入execjs模块前,让Popen的encoding参数锁定为utf-8。importsubprocessfromfunctoolsimportpartialsubprocess.Popen=partial(subprocess.Popen,encoding="utf-8") ......
  • selenium运行时的ValueError: Timeout value connect was <object object at 0x000001
    fromseleniumimportwebdriverdriver=webdriver.Chrome()driver.get("https://www.baidu.com/")运行时出现ValueError:Timeoutvalueconnectwas<objectobjectat0x000001FE483C4170>错误大概率原因是:selenium和urllib3库的版本冲突导致修改版本为:selenium=3.1......
  • js Object常用的方法
    Object.keys(obj)Object.keys(obj):返回对象自身所有可枚举属性的键名数组处理对象,返回可枚举的键数组constobject1={a:'somestring',b:42,c:false};console.log(Object.keys(object1));//结果:Array["a","b","c"]处理数组和字符串,返回索引值数组......