Detailed explanation of the working principle of js instanceof

According to MDN's explanation

The instanceof operator is used to detect whether the prototype property of the constructor appears on the prototype chain of an instance object.


s instanceof F is expressed by a recursive function, and the process is roughly as follows:

function _instanceof(s, F) {
    
    
	if(s.__proto__ === F.prototype) {
    
    
		// 找到目标
		return true
	} else if("__proto__" in F) {
    
    
		// 存在上一层原型1
		_instanceof(s, F.__proto__)
	} else {
    
    
		// 穷尽原型链仍找不到目标
		return false
	}
}
_instanceof(s, F)

The working principle of instanceof is to compare the __proto__ of each layer of s with F.prototype, and
return true if the same is found
until the last layer is still not found, return false




Because the prototype of the constructor can be modified (this is generally not recommended), the result returned by instanceof is not fixed, or even wrong.
Let us understand the reason through the following example

<html>

<head>
	<title>instanceof 的工作原理</title>
</head>

<body>

	<script type="text/javascript">
		function section1() {
     
     
			function F1() {
     
      }

			function F2() {
     
      }

			// F1.prototype 的粗略结构
			// F1_prototype = {
     
     
			// 	constructor: F1,
			// 	__proto__: {
     
     
			// 		constructor: Object
			// 	}
			// }

			// F2.prototype 的粗略结构
			// F2_prototype = {
     
     
			// 	constructor: F2,
			// 	__proto__: {
     
     
			// 		constructor: Object
			// 	}
			// }

			var s = new F1();

			// 根据实例化原理可知 s.__proto__ === F1.prototype
			console.log(s.__proto__ === F1.prototype) // true
			// 所以得以下结果
			console.log(s instanceof F1) // true

			// 根据 F2_prototype 显示的结构, s 整个原型链都没有 F2.prototype
			// 所以得以下结果
			console.log(s instanceof F2) // false

		}

		function section2() {
     
     
			function F1() {
     
      }

			// F1.prototype 的粗略结构
			// F1_prototype = {
     
     
			// 	constructor: F1,
			// 	__proto__: {
     
     
			// 		constructor: Object
			// 	}
			// }

			var s = new F1();
			// s 的粗略结构
			// _s = {
     
     
			// 	__proto__: {
     
     
			// 		constructor: F1,
			// 		__proto__: {
     
     
			// 			constructor: Object
			// 		}
			// 	}
			// }

			// *提示: {} 相当于新建一个对象, 与其它对象都不相等, 类似于 {} !== {}
			F1.prototype = {
     
     };

			// F1.prototype 的粗略结构
			// F1_prototype = {
     
     
			// 	__proto__: {
     
     
			// 		constructor: Object
			// 	}
			// }

			var s2 = new F1();

			// s2 的粗略结构
			// _s2 = {
     
     
			// 	__proto__: {
     
     
			// 		__proto__: {
     
     
			// 			constructor: Object
			// 		}
			// 	}
			// }

			// F1.prototype 重写后, F1.prototype 是一个新的对象, 不存在于 s 的原型链上
			// 所以得以下结果
			console.log(s instanceof F1) // false

			// 根据 F1_prototype, _s2 显示的结构
			console.log(s2.__proto__ === F1.prototype) // false
			// 所以得以下结果
			console.log(s2 instanceof F1) // true

		}

		function section3() {
     
     
			function F1() {
     
      }

			function F2() {
     
      }

			// F2.prototype 的粗略结构
			// F2_prototype = {
     
     
			// 	constructor: F2,
			// 	__proto__: {
     
     
			// 		constructor: Object
			// 	}
			// }

			var s = new F2();

			// 根据实例化原理可知 s.__proto__ === F2.prototype
			console.log(s.__proto__ === F2.prototype) // true
			// 所以得以下结果
			console.log(s instanceof F2) // true

			// 根据 F2_prototype 显示的结构, s 整个原型链都没有 F1.prototype
			// 所以得以下结果
			console.log(s instanceof F1) // false

		}

		function section4() {
     
     
			function F1() {
     
      }

			function F2() {
     
      }

			F2.prototype = new F1(); // 继承

			// F1.prototype 的粗略结构
			// F1_prototype = {
     
     
			// 	constructor: F1,
			// 	__proto__: {
     
     
			// 		constructor: Object
			// 	}
			// }

			// F2.prototype 的粗略结构
			// *提示: F2.prototype.__proto__ === F1.prototype
			// F2_prototype = {
     
     
			// 	constructor: undefined,
			// 	__proto__: {
     
     
			// 		constructor: F1,
			// 		__proto__: {
     
     
			// 			constructor: Object
			// 		}
			// 	}
			// }

			var s = new F2();

			// 根据实例化原理可知 s.__proto__ === F2.prototype
			console.log(s.__proto__ === F2.prototype) // true
			// 所以得以下结果
			console.log(s instanceof F2) // true

			// 根据 F2_prototype 显示的结构, 推理可得
			console.log(s.__proto__.__proto__ === F1.prototype)
			// 所以得以下结果
			console.log(s instanceof F1) // true

		}

		function section5() {
     
     
			function F1() {
     
      }

			function F2() {
     
      }

			F2.prototype = F1.prototype; // 继承

			// F1.prototype 的粗略结构
			// F1_prototype = {
     
     
			// 	constructor: F1,
			// 	__proto__: {
     
     
			// 		constructor: Object
			// 	}
			// }

			// F2.prototype 的粗略结构
			// F2_prototype = {
     
     
			// 	constructor: F1,
			// 	__proto__: {
     
     
			// 		constructor: Object
			// 	}
			// }

			var s = new F2();

			// 根据实例化原理可知 s.__proto__ === F2.prototype
			console.log(s.__proto__ === F2.prototype) // true
			// 所以得以下结果
			console.log(s instanceof F2) // true

			// 因为 F2.prototype 重写后就是 F1.prototype
			console.log(s.__proto__ === F1.prototype)
			// 所以得以下结果
			console.log(s instanceof F1) // true

		}

		section1()
		section2()
		section3()
		section4()
		section5()
	</script>
</body>

</html>

Because instanceof calculates the result through the prototype of the constructor, when the prototype is modified, the result of instanceof will also be affected

//end

Guess you like

Origin blog.csdn.net/u013970232/article/details/109405118