JS_javascript スキルのとんでもない valueOf メソッドの紹介
彭老湿近期月报里提到了valueOf方法,兴致来了翻了下ECMA5里关于valueOf方法的介绍,如下:
15.2.4.4 Object.prototype.valueOf ( )
When the valueOf method is called, the following steps are taken:
1. Let O be the result of calling ToObject passing the this value as the argument.
2. If O is the result of calling the Object constructor with a host object (15.2.2.1), then
a. Return either O or another value such as the host object originally passed to the constructor. The specific result that is returned is implementation-defined.
3. Return O.
规范里面的对于valueOf的解释很短,大致为:调用ToObject方法(一个抽象方法,后面会讲到),并将this的值作为参数传入。
针对调用ToObject时传入的不同参数(this),返回值分别如下:
1、this为宿主对象时,返回值取决于浏览器的实现,即不同浏览器的返回可能不同(关于宿主对象,可参考http://www.w3school.com.cn/js/pro_js_object_types.asp)
2、this不是宿主对象,则返回ToObject(this)的值
参数类型 | 返回结果 |
Undefined | 抛出TypeError异常 |
Null | 抛出TypeError异常 |
Number | 创建一个Number对象,它内部的初始值为传入的参数值 |
String | 创建一个String对象,它内部的初始值为传入的参数值 |
Boolean | 创建一个Boolean对象,它内部的初始值为传入的参数值 |
Object | 返回传入的参数(无转换) |
根据Object.prototype.valueOf的定义,以及抽象方法ToObject的描述,可得下表
obj类型 | Object.prototype.valueOf.call(obj)返回结果 |
Undefined | 抛出TypeError异常 |
Null | 抛出TypeError异常 |
Number | Number类型的对象,值等于obj |
String | String类型的对象,值等于obj |
Boolean | Boolean类型的对象,值等于obj |
Object | obj对象本身 |
举几个具体的例子:
var num = 123;
console.log(num.valueOf()); //输出:123
console.log(num.valueOf()); //输出:'number'
var unde = undefined;
console.log(Object.prototype.valueOf.call(unde)); //输出:'TypeError: Cannot convert null to object'
var obj = {name:'casper'};
var linkObj = obj.valueOf();
linkObj.name = 'change';
console.log(linkObj.name); //输出:'change' ...说明obj.valueOf()返回的是对象自身
实际上,上面没有提到Array、Function对象,根据下面代码可以猜想,当Object.prototype.valueOf调用时,参数为Array、Function类型的对象时,返回的结果也为对象自身:
var arr = [1, 2 ,3];
var linkArr = arr.valueOf();
linkArr[0] = ['casper'];
console.log(linkArr); //输出:['casper', 2, 3]
var foo = function(){ return 1; };
var linkFoo = foo.valueOf();
linkFoo.test = 'casper';
console.log(linkFoo.test); //输出:'casper'
看完上面的描述,是不是有种恍然大悟的感觉?如果是的话,恭喜你,可能你跟我一样其实还没完全理解透彻。
简单举个例子,当调用Object.prototype.valueOf的对象为数值类型时,假设该对象是名称为num,num很有可能通过下面两种方式声明:
var num = 123; //通过对象字面量声明console.log(typeof num); //输出:'number'
var num = new Number(123); //通过构造方法声明console.log(typeof num); //输出:'object'
更多变态声明方式,可参见《JS中不为人知的五种声明Number的方式》
关于返回值的说明,ECMA5里面原文如下:
Create a new Number object whose [[PrimitiveValue]] internal property is set to the value of the argument. See 15.7 for a description of Number objects.
按照这段文字的说明,似乎num.valueOf()返回的应该是个Number对象(非字面量声明的那种),但实际上:
var num = 123;
var tmp = num.valueOf();
console.log(typeof tmp); //输出: 'number'
这是怎么回事呢?于是又仔细翻看了下,似乎有些接近真相了:
5.7.4.4 Number.prototype.valueOf ( )
Returns this Number value.
The valueOf function is not generic; it throws a TypeError exception if its this value is not a Number or a Number object. Therefore, it cannot be transferred to other kinds of objects for use as a method.
原来Number有属于自身的原型valueOf方法,不是直接从Object.prototype上继承下来,类似的,Boolean、String也有自己的原型valueOf方法,归纳如下:
类型 | 是否有属于自己的原型valueOf方法 |
Undefined | 无 |
Null | 无 |
Number | 有,Number.prototype.valueOf |
String | 有,String.prototype.valueOf |
Boolean | 有,Boolean.prototype.valueOf |
Object | - |
참고 Array 프로토타입 개체에는 자체 valueOf 속성이 없지만 표준 내장 객체 프로토타입 객체
함수 프로토타입 객체에는 자체 valueOf 속성이 없지만 객체 프로토타입 객체에서 valueOf 속성을 상속합니다.
추가 참고 사항: Number.prototype.valueOf 내부 변환 규칙은 예상보다 조금 더 복잡하므로 여기서는 자세히 설명하지 않습니다. 2.valueOf 사용 시나리오, 실제 개발에 사용하는 형제는 본 적이 없습니다.
마지막 : 글의 예시에 오류나 누락이 있으면 글이 유용하다고 생각하시면 지적해주세요. 추천을 눌러주시면 됩니다 :)

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









フロントエンドのサーマルペーパーチケット印刷のためのよくある質問とソリューションフロントエンド開発におけるチケット印刷は、一般的な要件です。しかし、多くの開発者が実装しています...

スキルや業界のニーズに応じて、PythonおよびJavaScript開発者には絶対的な給与はありません。 1. Pythonは、データサイエンスと機械学習でさらに支払われる場合があります。 2。JavaScriptは、フロントエンドとフルスタックの開発に大きな需要があり、その給与もかなりです。 3。影響要因には、経験、地理的位置、会社の規模、特定のスキルが含まれます。

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

同じIDを持つ配列要素をJavaScriptの1つのオブジェクトにマージする方法は?データを処理するとき、私たちはしばしば同じIDを持つ必要性に遭遇します...

この記事の視差スクロールと要素のアニメーション効果の実現に関する議論では、Shiseidoの公式ウェブサイト(https://www.shisido.co.co.jp/sb/wonderland/)と同様の達成方法について説明します。

Console.log出力の違いの根本原因に関する詳細な議論。この記事では、Console.log関数の出力結果の違いをコードの一部で分析し、その背後にある理由を説明します。 �...

JavaScriptを学ぶことは難しくありませんが、挑戦的です。 1)変数、データ型、関数などの基本概念を理解します。2)非同期プログラミングをマスターし、イベントループを通じて実装します。 3)DOM操作を使用し、非同期リクエストを処理することを約束します。 4)一般的な間違いを避け、デバッグテクニックを使用します。 5)パフォーマンスを最適化し、ベストプラクティスに従ってください。

フロントエンドのVSCodeと同様に、パネルドラッグアンドドロップ調整機能の実装を調べます。フロントエンド開発では、VSCODEと同様のVSCODEを実装する方法...
