ตัวดำเนินการ instanceof ใน JavaScript คืออะไร


313

instanceofคำหลักใน JavaScript อาจจะค่อนข้างสับสนเมื่อมันเป็นครั้งแรกที่พบเป็นคนมักจะคิดว่า JavaScript ไม่ได้เป็นภาษาการเขียนโปรแกรมเชิงวัตถุ

  • มันคืออะไร?
  • มันแก้ปัญหาอะไรได้บ้าง?
  • มันเหมาะสมเมื่อใดและเมื่อใด

3
แม้ว่าคำตอบที่ร้องมีประโยชน์มากคุณไม่ได้ใช้มาก (อย่างน้อยฉันก็ไม่ได้) ในแอปพลิเคชั่นคำศัพท์ หนึ่งจะทำให้คุณสมบัติ object.type ที่ถือสตริงและตรวจสอบมัน
Omar Al-Ithawi

4
JS ไม่สมเหตุสมผล: "foo" instanceof String=> false, 1 instanceof Number=> false, {} instanceof Object=> false พูดว่าอะไรนะ?!
morbusg

12
@morbusg ความคิดเห็นของคุณทำให้เข้าใจผิด ครั้งแรกที่ถูกต้องเพราะ"foo" instanceof String => false เพราะ- คุณควรปฏิบัติหน้าที่เหมือนคลาส (นิยามของคลาส) ตัวแปรกลายเป็นบางส่วน(ชั้น) เมื่อคุณกำหนดเป็น เช่นเดียวกับ - 'number' ไม่ใช่ 'function' :) ถัดไป - อยู่ในโหนดและเบราว์เซอร์สมัยใหม่typeof "foo" == 'string'new String("foo") instanceof String => truetypeof String == 'function'instanceoffunctionvar v = new AnythingWhatTypeofEqualsFunction()1typeof 1 == 'number'{} instanceof ObjectTRUE
fider

1
@fider: นั่นเป็นความเห็นที่มีต่อสเป็คภาษาที่มาจากรูบี้
morbusg

@morbusg - จะกลับมา({}) instanceof Object trueในความเป็นจริงรหัสที่คุณเขียนจะทำให้คุณมีข้อผิดพลาด
DDM

คำตอบ:


279

instanceof

ตัวถูกดำเนินการด้านซ้ายมือ (LHS) เป็นวัตถุจริงที่กำลังทดสอบกับตัวถูกดำเนินการด้านขวามือ (RHS) ซึ่งเป็นตัวสร้างที่แท้จริงของคลาส คำจำกัดความพื้นฐานคือ:

Checks the current object and returns true if the object
is of the specified object type.

นี่คือตัวอย่างที่ดีและนี่คือตัวอย่างที่นำมาโดยตรงจากเว็บไซต์นักพัฒนาของ Mozilla :

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral"; //no type specified
color2 instanceof String; // returns false (color2 is not a String object)

สิ่งหนึ่งที่ควรค่าแก่การกล่าวถึงคือinstanceofประเมินว่าเป็นจริงถ้าวัตถุสืบทอดมาจากต้นแบบของคลาส:

var p = new Person("Jon");
p instanceof Person

นั่นคือp instanceof Personเป็นความจริงตั้งแต่สืบทอดจากpPerson.prototype

ตามคำขอของ OP

ฉันได้เพิ่มตัวอย่างเล็ก ๆ ที่มีรหัสตัวอย่างและคำอธิบาย

เมื่อคุณประกาศตัวแปรคุณให้ประเภทเฉพาะ

ตัวอย่างเช่น

int i;
float f;
Customer c;

การแสดงดังกล่าวข้างต้นบางตัวแปรคือi, และf cชนิดที่มีinteger, floatและผู้ใช้กำหนดCustomerชนิดข้อมูล ประเภทดังกล่าวข้างต้นอาจเป็นภาษาใดก็ได้ไม่ใช่แค่ JavaScript อย่างไรก็ตามด้วย JavaScript เมื่อคุณประกาศตัวแปรที่คุณไม่ได้กำหนดประเภทไว้อย่างชัดเจนvar xx อาจเป็นตัวเลข / สตริง / ประเภทข้อมูลที่ผู้ใช้กำหนด ดังนั้นinstanceofมันคืออะไรตรวจสอบวัตถุเพื่อดูว่าเป็นชนิดที่ระบุไว้จากข้างบนรับCustomerวัตถุที่เราสามารถทำได้:

var c = new Customer();
c instanceof Customer; //Returns true as c is just a customer
c instanceof String; //Returns false as c is not a string, it's a customer silly!

ดังกล่าวข้างต้นที่เราเคยเห็นว่ามีการประกาศกับชนิดc Customerเราเพิ่งตรวจสอบแล้วว่าเป็นประเภทCustomerหรือไม่ แน่นอนมันจะกลับมาจริง จากนั้นยังคงใช้วัตถุที่เราตรวจสอบถ้ามันเป็นCustomer Stringไม่ใช่แน่นอนStringเราCustomerไม่ใช่วัตถุที่ไม่ใช่Stringวัตถุวัตถุ ในกรณีนี้มันจะคืนค่าเท็จ

มันง่ายจริงๆ!


@Alon - ฉันได้เพิ่มตัวอย่างสำหรับคุณ ดูข้างต้น color1 เป็นสตริงประเภทดังนั้นเมื่อคุณพูดว่าcolor1 instanceof String;สิ่งนี้จะส่งกลับจริงเพราะ color1 เป็นสตริง
JonH

@Alon - ตรวจสอบวัตถุเพื่อดูว่าเป็นวัตถุประเภทใด พิจารณาบุคคล / ลูกค้าวัตถุ ดังนั้นperson p = new person()p คือประเภทบุคคลและไม่ใช่ประเภทสตริง
JonH

ใน JavaScript อาจเป็นเรื่องยากที่จะเข้าใจว่าตัวแปรมีความยืดหยุ่นในการมีประเภทที่แตกต่างกันตลอดช่วงอายุการใช้งาน ตัวอย่างเช่นรหัสสินค้า: jsfiddle.net/sikusikucom/znSPv
moey

@ Siku-Siku.Com - ฉันไม่เห็นกลอุบายใด ๆ กับมันvar zero = 0; alert(zero); zero = "0"; alert(zero)เราเปลี่ยนจากแบบดั้งเดิมintเป็นแบบดั้งเดิมstringโดยไม่มีปัญหาใด ๆ
JonH

โอ้ฉันหมายความว่ามันเป็นเรื่องยาก / ใหม่ที่จะเข้าใจ (ไม่ทำ ) ว่า "ความยืดหยุ่น" ใน JavaScript, esp สำหรับบางคนที่เคยชินกับภาษาที่ต้องการเช่นการคัดเลือกนักแสดงที่ชัดเจนเพื่อเปลี่ยนประเภทของตัวแปร ในขณะที่คุณชี้ให้เห็นว่ามันง่ายมากที่จะเปลี่ยนประเภทจากเช่นดั้งเดิมเพื่อดั้งเดิมint string
moey

95

มีแง่มุมที่สำคัญสำหรับอินสแตนซ์ที่ดูเหมือนจะไม่ครอบคลุมในความคิดเห็นใด ๆ : การสืบทอด ตัวแปรที่ถูกประเมินโดยการใช้งานของ instanceof สามารถคืนค่าจริงสำหรับ "หลายประเภท" เนื่องจากการสืบทอดต้นแบบ

ตัวอย่างเช่นลองกำหนดประเภทและประเภทย่อย:

function Foo(){ //a Foo constructor
    //assign some props
    return this;
}

function SubFoo(){ //a SubFoo constructor
    Foo.call( this ); //inherit static props
    //assign some new props
    return this;
}

SubFoo.prototype = Object.create(Foo.prototype); // Inherit prototype
SubFoo.prototype.constructor = SubFoo;

ตอนนี้เรามี "คลาส" สองสามตัวที่ช่วยให้สร้างอินสแตนซ์และค้นหาว่าอินสแตนซ์ของพวกเขาคืออะไร:

var 
    foo = new Foo()
,   subfoo = new SubFoo()
;

alert( 
    "Q: Is foo an instance of Foo? "
+   "A: " + ( foo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is foo an instance of SubFoo? " 
+   "A: " + ( foo instanceof SubFoo ) 
); // -> false

alert( 
    "Q: Is subfoo an instance of Foo? "
+   "A: " + ( subfoo instanceof Foo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of SubFoo? "
+   "A: " + ( subfoo instanceof SubFoo ) 
); // -> true

alert( 
    "Q: Is subfoo an instance of Object? "
+   "A: " + ( subfoo instanceof Object ) 
); // -> true

เห็นไหมว่าบรรทัดสุดท้าย? การเรียก "ใหม่" ทั้งหมดไปยังฟังก์ชันส่งคืนออบเจ็กต์ที่สืบทอดจาก Object สิ่งนี้ถือเป็นจริงแม้ว่าจะใช้การสร้างวัตถุแบบย่อ:

alert( 
    "Q: Is {} an instance of Object? "
+   "A: " + ( {} instanceof Object ) 
); // -> true

แล้วคำจำกัดความของ "คลาส" นั้นคืออะไร? พวกมันคืออะไร

alert( 
    "Q: Is Foo an instance of Object? "
+   "A:" + ( Foo instanceof Object) 
); // -> true

alert( 
    "Q: Is Foo an instance of Function? "
+   "A:" + ( Foo instanceof Function) 
); // -> true

ผมรู้สึกว่าการทำความเข้าใจว่าวัตถุใด ๆ ที่สามารถเป็นตัวอย่างของหลายประเภทเป็นสิ่งสำคัญเนื่องจากคุณของฉัน (ถูก) instanceofสมมติว่าคุณสามารถแยกความแตกต่างระหว่างการพูดและวัตถุและการทำงานโดยการใช้ เป็นตัวอย่างสุดท้ายนี้แสดงให้เห็นชัดเจนว่าฟังก์ชั่นคือวัตถุ

สิ่งนี้ก็มีความสำคัญเช่นกันหากคุณใช้รูปแบบการสืบทอดและต้องการยืนยันลูกหลานของวัตถุด้วยวิธีอื่นนอกเหนือจากการพิมพ์ด้วยเป็ด

instanceofหวังว่าจะช่วยให้ทุกคนสำรวจ


น่ากลัวยิ่งกว่าคือหลังจากที่คุณได้รับมรดกจากต้นแบบพร้อมกับSubFoo.prototype = new Foo();คุณสามารถเพิ่มวิธีการเพิ่มเติมได้และการsubfoo instanceof Fooตรวจสอบจะยังคงดำเนินต่อไปเช่นกันsubfoo instanceof SubFoo
Cory Danielson

87

คำตอบอื่น ๆ ที่นี่ถูกต้อง แต่พวกเขาไม่เข้าใจวิธีการinstanceofใช้งานจริงซึ่งอาจเป็นที่สนใจของนักกฎหมายด้านภาษาบางคน

วัตถุทุกชิ้นใน JavaScript มีต้นแบบซึ่งสามารถเข้าถึงได้ผ่าน__proto__คุณสมบัติ ฟังก์ชั่นยังมีprototypeคุณสมบัติซึ่งเป็นค่าเริ่มต้น__proto__สำหรับวัตถุใด ๆ ที่สร้างขึ้นโดยพวกเขา prototypeเมื่อมีฟังก์ชั่นจะถูกสร้างขึ้นก็จะได้รับวัตถุที่ไม่ซ้ำกันสำหรับ instanceofผู้ประกอบการใช้เป็นเอกลักษณ์นี้เพื่อให้คำตอบ นี่คือสิ่งที่instanceofอาจดูเหมือนว่าคุณเขียนมันเป็นฟังก์ชั่น

function instance_of(V, F) {
  var O = F.prototype;
  V = V.__proto__;
  while (true) {
    if (V === null)
      return false;
    if (O === V)
      return true;
    V = V.__proto__;
  }
}

นี่คือการถอดความรุ่น ECMA-262 5.1 (หรือที่เรียกว่า ES5) ส่วนที่ 15.3.5.3

โปรดทราบว่าคุณสามารถกำหนดวัตถุใด ๆ ให้กับprototypeคุณสมบัติของฟังก์ชันอีกครั้งและคุณสามารถกำหนด__proto__คุณสมบัติของวัตถุใหม่หลังจากที่สร้างขึ้นแล้ว สิ่งนี้จะให้ผลลัพธ์ที่น่าสนใจแก่คุณ:

function F() { }
function G() { }
var p = {};
F.prototype = p;
G.prototype = p;
var f = new F();
var g = new G();

f instanceof F;   // returns true
f instanceof G;   // returns true
g instanceof F;   // returns true
g instanceof G;   // returns true

F.prototype = {};
f instanceof F;   // returns false
g.__proto__ = {};
g instanceof G;   // returns false

5
เป็นที่น่าสังเกตว่าการอนุญาตโดยตรงของ__proto__คุณสมบัติ "" ไม่ได้รับอนุญาตใน IE ถ้าฉันจำได้อย่างถูกต้องการจัดการโดยตรงของคุณสมบัติจะไม่รวมอยู่ในข้อมูลจำเพาะของ ECMA ดังนั้นอาจเป็นความคิดที่ดีที่จะใช้มันสำหรับการมอบหมายอื่น ๆ นอกเหนือจากในการศึกษาเชิงวิชาการ
webnesto

@webnesto นั่นเป็นความจริงโปรโตไม่ได้อยู่ในสเป็ค ฉันไม่ทราบว่า IE ไม่รองรับ เมื่อคุณพูดถึงการยักย้ายโดยตรงคุณหมายความว่ามันไม่ได้เปิดเผยรหัส JS เลยหรือไม่ใช่แค่เขียนได้?
Jay Conrod

2
ไม่แน่ใจ 100% สำหรับเวอร์ชั่นเก่า เสียงเหมือนมาจากที่นี่ ( stackoverflow.com/questions/8413505/proto-for-ie9-or-ie10 ) ซึ่งใน IE9 เป็นอย่างน้อยสามารถอ่านได้ (แม้ว่าจะไม่แน่นอน) นอกจากนี้ยังมีข้อควรระวังที่ดูเหมือนว่าเบราว์เซอร์อาจถูกทิ้งไว้โดยสิ้นเชิง
webnesto

4
การเข้าใจถึงการมีอยู่ของคุณสมบัติโปรโตนั้นเป็นสิ่งสำคัญไม่ว่าผู้ใช้จะสามารถเข้าถึงได้ด้วยรหัสหรือไม่ +10 ถ้าฉันทำได้สำหรับการอ้างถึงสเป็คนี่คือสิ่งที่ฉันมาที่นี่เพื่อค้นหา
Mike Edwards

3
ในการรับลิงค์ต้นแบบให้ใช้Object.getPrototypeOf(o)สิ่งนี้จะเหมือนกับที่__proto__คุณอธิบาย แต่เป็นไปตาม ECMAScript
froginvasion

45

ฉันคิดว่ามันคุ้มค่าที่จะสังเกตว่าอินสแตนซ์ของมันถูกกำหนดโดยการใช้คำหลัก "ใหม่" เมื่อประกาศวัตถุ ในตัวอย่างจาก JonH;

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)

สิ่งที่เขาไม่ได้เอ่ยถึงคือสิ่งนี้

var color1 = String("green");
color1 instanceof String; // returns false

การระบุ "ใหม่" คัดลอกสถานะสิ้นสุดจริงของฟังก์ชันตัวสร้างสตริงลงใน color1 var แทนที่จะตั้งค่าเป็นค่าส่งคืน ฉันคิดว่าสิ่งนี้จะแสดงสิ่งที่ดีกว่าคำหลักใหม่

function Test(name){
    this.test = function(){
        return 'This will only work through the "new" keyword.';
    }
    return name;
}

var test = new Test('test');
test.test(); // returns 'This will only work through the "new" keyword.'
test // returns the instance object of the Test() function.

var test = Test('test');
test.test(); // throws TypeError: Object #<Test> has no method 'test'
test // returns 'test'

การใช้ "ใหม่" กำหนดค่าของ "this" ภายในฟังก์ชันให้กับ var ที่ประกาศขณะที่ไม่ได้ใช้จะกำหนดค่าส่งคืนแทน


2
ไม่เหมาะสมที่จะใช้newกับ JavaScript ทุกประเภทซึ่งทำให้คำตอบที่ได้รับการยอมรับมีความสับสนมากขึ้นสำหรับผู้เริ่มต้น text = String('test')และoptions = {}จะไม่ถูกทดสอบด้วยinstanceofแต่ให้typeofแทนที่ด้วย
Ryan

3
Date.getTime () // ล้มเหลว ใช่ใหม่เป็นสิ่งสำคัญ
Stephen Belanger

1
ลองใช้สิ่งนั้นในคอนโซล คุณจะได้รับข้อผิดพลาดเนื่องจากไม่มี getTime () คุณจำเป็นต้องใช้ใหม่
Stephen Belanger

8

และคุณสามารถใช้มันสำหรับการจัดการและแก้ไขข้อผิดพลาดเช่นนี้:

try{
    somefunction();
} 
catch(error){
    if (error instanceof TypeError) {
        // Handle type Error
    } else if (error instanceof ReferenceError) {
        // Handle ReferenceError
    } else {
        // Handle all other error types
    }
}

3
//Vehicle is a function. But by naming conventions
//(first letter is uppercase), it is also an object
//constructor function ("class").
function Vehicle(numWheels) {
    this.numWheels = numWheels;
}

//We can create new instances and check their types.
myRoadster = new Vehicle(4);
alert(myRoadster instanceof Vehicle);

3

มันคืออะไร?

Javascript เป็นภาษาต้นแบบซึ่งหมายความว่ามันใช้ต้นแบบสำหรับ 'การสืบทอด' instanceofประกอบการทดสอบถ้าฟังก์ชั่นคอนสตรัคของprototypepropertype อยู่ใน__proto__ห่วงโซ่ของวัตถุ ซึ่งหมายความว่าจะทำดังต่อไปนี้ (สมมติว่า testObj เป็นวัตถุฟังก์ชั่น):

obj instanceof testObj;
  1. ตรวจสอบว่าต้นแบบของวัตถุเท่ากับต้นแบบของตัวสร้าง: obj.__proto__ === testObj.prototype >> ถ้ามันtrue instanceofจะกลับมาtrueจะกลับมา
  2. จะปีนขึ้นไปต้นแบบลูกโซ่ ตัวอย่างเช่น: obj.__proto__.__proto__ === testObj.prototype >> ถ้าเป็นจะกลับมาtrue instanceoftrue
  3. จะทำซ้ำขั้นตอนที่ 2 จนกว่าจะตรวจสอบต้นแบบเต็มของวัตถุ หากไม่มีที่ไหนในห่วงโซ่ต้นแบบของวัตถุที่ถูกจับคู่กับtestObj.prototypeจากนั้นผู้ประกอบการจะกลับมาinstanceoffalse

ตัวอย่าง:

function Person(name) {
  this.name = name;
}
var me = new Person('Willem');

console.log(me instanceof Person); // true
// because:  me.__proto__ === Person.prototype  // evaluates true

console.log(me instanceof Object); // true
// because:  me.__proto__.__proto__ === Object.prototype  // evaluates true

console.log(me instanceof Array);  // false
// because: Array is nowhere on the prototype chain

มันแก้ปัญหาอะไรได้บ้าง?

มันแก้ปัญหาการตรวจสอบได้อย่างสะดวกสบายถ้าวัตถุนั้นมาจากต้นแบบที่แน่นอน ตัวอย่างเช่นเมื่อฟังก์ชั่นรับวัตถุซึ่งสามารถมีต้นแบบต่าง ๆ จากนั้นก่อนที่จะใช้วิธีการจากห่วงโซ่ต้นแบบเราสามารถใช้ตัวinstanceofดำเนินการเพื่อตรวจสอบว่าวิธีการเหล่านี้อยู่บนวัตถุ

ตัวอย่าง:

function Person1 (name) {
  this.name = name;
}

function Person2 (name) {
  this.name = name;
}

Person1.prototype.talkP1 = function () {
  console.log('Person 1 talking');
}

Person2.prototype.talkP2 = function () {
  console.log('Person 2 talking');
}


function talk (person) {
  if (person instanceof Person1) {
    person.talkP1();
  }
  
  if (person instanceof Person2) {
    person.talkP2();
  }
  
  
}

const pers1 = new Person1 ('p1');
const pers2 = new Person2 ('p2');

talk(pers1);
talk(pers2);

ที่นี่ในtalk()ฟังก์ชั่นก่อนมีการตรวจสอบว่าต้นแบบอยู่บนวัตถุ หลังจากนี้จะมีการเลือกวิธีการที่เหมาะสมเพื่อดำเนินการ การไม่ตรวจสอบนี้อาจส่งผลให้เกิดการดำเนินการวิธีการที่ไม่มีอยู่และทำให้เกิดข้อผิดพลาดในการอ้างอิง

มันเหมาะสมเมื่อใดและเมื่อใด

พวกเราไปที่นี่แล้ว ใช้มันเมื่อคุณต้องการตรวจสอบต้นแบบของวัตถุก่อนที่จะทำอะไรกับมัน


1
ฉันคิดว่าคุณต้องการที่จะเขียนอย่างอื่นมากกว่า " ต้นแบบของฟังก์ชั่นคอนสตรัคเตอร์ปรากฏที่ใดที่หนึ่งในคุณสมบัติต้นแบบของคอนสตรัคเตอร์ "
Bergi

คุณอาจต้องการพูดถึงว่าเป็นการเหมาะสมที่จะให้บุคคลแบ่งปันอินเตอร์เฟสและตั้งชื่อทั้งสองวิธีPersonX.prototype.talkเพื่อให้talkฟังก์ชันสามารถทำได้ง่ายperson.talk()ขึ้น
Bergi

คุณได้รับการอัปเดตอย่างสมบูรณ์ดังนั้นคำนิยามจึงดีกว่า ขอบคุณสำหรับการชี้!
วิลเล็มแวนเดอร์วีน

นอกจากนี้อย่าใช้__proto__ในเอกสารมันเลิกใช้แล้ว - เขียนObject.getPrototype()แทน
Bergi

1

ในคำถาม "เมื่อใดเหมาะสมและเมื่อไม่เหมาะสม" 2 cents ของฉัน:

instanceofไม่ค่อยมีประโยชน์ในรหัสการผลิต แต่มีประโยชน์ในการทดสอบที่คุณต้องการยืนยันว่ารหัสของคุณส่งคืน / สร้างวัตถุประเภทที่ถูกต้อง ด้วยความชัดเจนเกี่ยวกับประเภทของวัตถุที่โค้ดของคุณส่งคืน / สร้างการทดสอบของคุณจะมีประสิทธิภาพมากขึ้นเป็นเครื่องมือสำหรับการทำความเข้าใจและจัดทำเอกสารโค้ดของคุณ


1

instanceofเป็นเพียงน้ำตาล syntactic สำหรับisPrototypeOf:

function Ctor() {}
var o = new Ctor();

o instanceof Ctor; // true
Ctor.prototype.isPrototypeOf(o); // true

o instanceof Ctor === Ctor.prototype.isPrototypeOf(o); // equivalent

instanceof เพียงแค่ขึ้นอยู่กับต้นแบบของตัวสร้างของวัตถุ

ตัวสร้างเป็นเพียงฟังก์ชั่นปกติ พูดอย่างเคร่งครัดมันเป็นวัตถุฟังก์ชั่นเนื่องจากทุกอย่างเป็นวัตถุใน Javascript และฟังก์ชั่นวัตถุนี้มีต้นแบบเพราะทุกฟังก์ชั่นมีต้นแบบ

ต้นแบบเป็นเพียงวัตถุปกติซึ่งตั้งอยู่ภายในสายโซ่ต้นแบบของวัตถุอื่น นั่นหมายถึงการอยู่ในห่วงโซ่ต้นแบบของวัตถุอื่นทำให้วัตถุไปยังต้นแบบ:

function f() {} //  ordinary function
var o = {}, // ordinary object
 p;

f.prototype = o; // oops, o is a prototype now
p = new f(); // oops, f is a constructor now

o.isPrototypeOf(p); // true
p instanceof f; // true

instanceofผู้ประกอบการควรหลีกเลี่ยงเพราะมันปลอมเรียนซึ่งไม่อยู่ใน Javascript แม้จะมีclassคำสำคัญไม่ได้อยู่ใน ES2015 เช่นกันเพราะclassมันเป็นเพียงแค่ประโยคน้ำตาลสำหรับ ... แต่นั่นเป็นอีกเรื่อง


1
บรรทัดแรกไม่ถูกต้อง! ดูที่นี่สำหรับข้อมูลเพิ่มเติม: "isPrototypeOf () แตกต่างจากตัวดำเนินการ instanceof ในนิพจน์" วัตถุอินสแตนซ์ของ AFunction "นิพจน์ออบเจ็กต์ต้นแบบของวัตถุจะถูกตรวจสอบกับ AFunction.prototype
Yan Foto

1
@Yan และยังคงได้รับมาจากinstanceof isPrototypeOfฉันเรียกน้ำตาลน้ำตาลประโยคนี้ และแหล่งที่มา MDN ของคุณเป็นเรื่องตลกใช่มั้ย

ไม่มันไม่ใช่และไม่ควรจะเป็นเรื่องตลกแต่ก็ยังเป็นลิงก์ที่ผิด ฉันก็หมายความว่าจะมีคนนี้โพสต์ ฉันไม่ต้องการที่จะได้รับในทางเทคนิค แต่instanceof ไม่ได้isPrototypeOfทำในสิ่งเดียวกับ แค่นั้นแหละ.
Yan Foto

0

ฉันเพิ่งพบแอปพลิเคชันในโลกแห่งความเป็นจริงและฉันจะใช้บ่อยขึ้นในตอนนี้ฉันคิดว่า

หากคุณใช้เหตุการณ์ jQuery บางครั้งคุณต้องการเขียนฟังก์ชันทั่วไปซึ่งอาจเรียกได้โดยตรง (โดยไม่มีเหตุการณ์) คุณสามารถใช้instanceofเพื่อตรวจสอบว่าพารามิเตอร์แรกของฟังก์ชันของคุณเป็นตัวอย่างjQuery.Eventและตอบสนองอย่างเหมาะสม

var myFunction = function (el) {                
    if (el instanceof $.Event) 
        // event specific code
    else
        // generic code
};

$('button').click(recalc);    // Will execute event specific code
recalc('myParameter');  // Will execute generic code

ในกรณีของฉันฟังก์ชั่นที่จำเป็นในการคำนวณบางอย่างสำหรับทุกคน (ผ่านเหตุการณ์คลิกที่ปุ่ม) หรือองค์ประกอบที่เฉพาะเจาะจงเพียงอย่างเดียว รหัสที่ฉันใช้:

var recalc = function (el) { 
    el = (el == undefined || el instanceof $.Event) ? $('span.allItems') : $(el);
    // calculate...
};
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.