You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// eslint-disable-next-line es-x/no-object-getownpropertydescriptor -- safevargetOwnPropertyDescriptor=Object.getOwnPropertyDescriptor;varclassRegExp=/^\s*class\b/;varexec=uncurryThis(classRegExp.exec);varisClassConstructor=function(argument){try{// `Function#toString` throws on some built-it function in some legacy engines// (for example, `DOMQuad` and similar in FF41-)// 判断环境支持和排除classif(!DESCRIPTORS||!exec(classRegExp,inspectSource(argument)))returnfalse;}catch(error){/* empty */}// 拿到prototypevarprototype=getOwnPropertyDescriptor(argument,'prototype');// 判断prototype是否可写,普通函数的prototype是可写的,class相反return!!prototype&&hasOwn(prototype,'writable')&&!prototype.writable;};// `Function.isCallable` method$({target: 'Function',stat: true,sham: true,forced: true},{isCallable: functionisCallable(argument){// $iCallable: typeof argument == 'function' return$isCallable(argument)&&!isClassConstructor(argument);}});
varuncurryThis=require('../internals/function-uncurry-this');// fails:通过执行try catch包裹返回入参函数执行结果,如果报错返回truevarfails=require('../internals/fails');varisCallable=require('../internals/is-callable');// 相当于Object.prototype.toString.call.slice(argument,8,-1)varclassof=require('../internals/classof');// 获取内部函数vargetBuiltIn=require('../internals/get-built-in');// inspectSource:返回argument.toString()varinspectSource=require('../internals/inspect-source');varnoop=function(){/* empty */};varempty=[];// 拿到Reflect.construct函数varconstruct=getBuiltIn('Reflect','construct');varconstructorRegExp=/^\s*(?:class|function)\b/;varexec=uncurryThis(constructorRegExp.exec);varINCORRECT_TO_STRING=!constructorRegExp.exec(noop);varisConstructorModern=functionisConstructor(argument){if(!isCallable(argument))returnfalse;try{construct(noop,empty,argument);returntrue;}catch(error){returnfalse;}};varisConstructorLegacy=functionisConstructor(argument){if(!isCallable(argument))returnfalse;switch(classof(argument)){case'AsyncFunction':
case'GeneratorFunction':
case'AsyncGeneratorFunction': returnfalse;}try{// we can't check .prototype since constructors produced by .bind haven't it// `Function#toString` throws on some built-it function in some legacy engines// (for example, `DOMQuad` and similar in FF41-)// 某些环境,通过.bind函数生成的函数没有Function#toString值// 如果argument是一个箭头函数,通过exec正则匹配后返回falsereturnINCORRECT_TO_STRING||!!exec(constructorRegExp,inspectSource(argument));}catch(error){returntrue;}};isConstructorLegacy.sham=true;// `IsConstructor` abstract operation// https://tc39.es/ecma262/#sec-isconstructormodule.exports=!construct||fails(function(){// 可以看到通过判断环境支持分为两种模式,// 如果环境支持construct// isConstructorLegacy// isConstructorModernvarcalled;returnisConstructorModern(isConstructorModern.call)||!isConstructorModern(Object)||!isConstructorModern(function(){called=true;})||called;}) ? isConstructorLegacy : isConstructorModern;
可以看到最后有很多判断,下面逐个分析下
isConstructorModern(isConstructorModern.call)
报错 错误信息TypeError: function call() { [native code] } is not a constructor
返回false
!isConstructorModern(Object)
返回false
!isConstructorModern(function () { called = true; })
function-is-callable-is-constructor
isCallable
isConstructor
可以看到最后有很多判断,下面逐个分析下
isConstructorModern(isConstructorModern.call)
TypeError: function call() { [native code] } is not a constructor
false
!isConstructorModern(Object)
false
!isConstructorModern(function () { called = true; })
construct
api调用,入参的函数是不会被执行的,也就是called为undefinedfalse
三种情况个人理解是为了判断js执行环境,排除
[native code]
函数、检测Object构造函数返回情况、检测入参函数是否会被调用The text was updated successfully, but these errors were encountered: