this
キーワードを使用してコンストラクターが呼び出されたときに、Javascriptのreturnステートメントがnew
以外の値を返す正確な状況は何ですか?
例:
function Foo () {
return something;
}
var foo = new Foo ();
間違っていない場合、something
が非関数プリミティブの場合、this
が返されます。それ以外の場合は、something
が返されます。これは正しいです?
IOW、どの値がsomething
で(new Foo () instanceof Foo) === false
?
正確な条件は、 new
演算子で使用される_[[Construct]]
_内部プロパティで説明されています。
ECMA-262 3日から。エディションの仕様:
13.2.2 _
[[Construct]]
_
Function
オブジェクトF
の_[[Construct]]
_プロパティが呼び出されると、次の手順が実行されます。
- 新しいネイティブECMAScriptオブジェクトを作成します。
Result(1)
の _[[Class]]
_ プロパティを_"Object"
_に設定します。F
のプロトタイププロパティの値を取得します。Result(3)
がオブジェクトの場合、Result(1)
の _[[Prototype]]
_ プロパティをResult(3)
に設定します。Result(3)
がオブジェクトでない場合、Result(1)
の _[[Prototype]]
_ プロパティを元のObject
に設定します 15.2.3.1 で説明されているプロトタイプオブジェクト。F
の _[[Call]]
_ プロパティを呼び出し、this
値としてResult(1)
を提供し、引数リストを提供します引数値として_[[Construct]]
_に渡されます。Type(Result(6))
がObject
の場合、Result(6)
を返します。Result(1)
を返します。手順7と8を見ると、
Result(6)
(F
コンストラクター関数から返される値)の型がの場合にのみ新しいオブジェクトが返されます。 notオブジェクト。
具体例 http://jsbin.com/zivivucahi/1/edit?html,js,console,output
/*
ECMA 262 v 5
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
"4.3.2
primitive value
member of one of the types Undefined, Null, Boolean, Number, Symbol, or String as defined in clause 6"
*/
var Person = function(x){
return x;
};
console.log(Person.constructor);
console.log(Person.prototype.constructor);
console.log(typeof(Person));
console.log(typeof(Person.prototype));
function log(x){
console.log(x instanceof Person);
console.log(typeof x);
console.log(typeof x.prototype);
}
log(new Person(undefined));
log(new Person(null));
log(new Person(true));
log(new Person(2));
log(new Person(""));
//returns a function not an object
log(new Person(function(){}));
//implementation?
//log(new Person(Symbol('%')));
この問題に関するドキュメントは見つかりませんでしたが、あなたは正しいと思います。たとえば、コンストラクタからnew Number(5)
を返すことはできますが、リテラル5
を返すことはできません(無視され、代わりにthis
が返されます)。
簡単な言葉でいくつかのポイントをしようとしています。
JavaScriptでは、関数でnew
キーワードを使用し、次の場合、
function User() {
this.name = 'Virat'
}
var user = new User();
console.log(user.name); //=> 'Virat'
user
変数は返された複合オブジェクトを保持しますfunction User() {
this.name = 'Virat';
return function(){};
}
var user = new User();
console.log(user.name); //=> undefined
console.log(user); //=> function
function User() {
this.name = 'Virat';
return 10;
}
var user = new User();
console.log(user.name); //=> 'Virat'
補足として、戻り値またはthis
は方程式の一部にすぎません。
たとえば、これを考慮してください:
_function Two() { return new Number(2); }
var two = new Two;
two + 2; // 4
two.valueOf = function() { return 3; }
two + 2; // 5
two.valueOf = function() { return '2'; }
two + 2; // '22'
_
ご覧のとおり、.valueOf()
は内部的に使用され、楽しみと利益のために悪用される可能性があります。次のような副作用を作成することもできます。
_function AutoIncrementingNumber(start) {
var n = new Number, val = start || 0;
n.valueOf = function() { return val++; };
return n;
}
var auto = new AutoIncrementingNumber(42);
auto + 1; // 43
auto + 1; // 44
auto + 1; // 45
_
これにはsomeのような実用的なアプリケーションが必要だと想像できます。また、明示的にNumber
である必要はありません。オブジェクトに_.valueOf
_を追加すると、数値として動作できます。
_({valueOf: function() { return Math.random(); }}) + 1; // 1.6451723610516638
_
これを利用して、たとえば、常に新しいGUIDを返すオブジェクトを作成できます。