检查" instanceof"会失败的

时间:2017-04-07 02:24:49

标签: javascript prototype

      public void btnRegistrationUser_Click(View v) {
        final String email = txtEmailAddress.getText().toString();
        final String password = txtPassword.getText().toString();
        final String username = txtUsername.getText().toString();
        final ProgressDialog progressDialog = ProgressDialog.show(RegistrationActivity.this, "Please wait...", "Processing...", true);
        (firebaseAuth.createUserWithEmailAndPassword(email,password ))
                .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        progressDialog.dismiss();

                        if (task.isSuccessful()) {
                            //Sign in the user here
                            signin(email,password,username);

                        }
                        else
                        {
                            Log.e("ERROR", task.getException().toString());
                            Toast.makeText(RegistrationActivity.this, task.getException().getMessage(), Toast.LENGTH_LONG).show();
                        }
                    }
                });
    }

    private void signin(String email, String password, final String username) {
        firebaseAuth.signInWithEmailAndPassword(email, password)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            //New Account is signed in and now the Current User
                            FirebaseUser user = firebaseAuth.getInstance().getCurrentUser();
                            Toast.makeText(RegistrationActivity.this, "curr user is "+user.getEmail(), Toast.LENGTH_LONG).show();

                            UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder()
                                    .setDisplayName(username)
                                    .build();
                            user.updateProfile(profileUpdates)
                                .addOnCompleteListener(new OnCompleteListener<Void>() {
                                 @Override
                                public void onComplete(@NonNull Task<Void> task) {
                                    if (task.isSuccessful()) {
                                        Toast.makeText(RegistrationActivity.this, "curr display name is "+user.getDisplayName(), Toast.LENGTH_LONG).show(); 
                                    }
                                }
                            });


                            Intent i = new Intent(RegistrationActivity.this, LoginActivity.class);
                            startActivity(i);
                        }
                    }
                });

正如您所看到的,如果构造函数的原型不是对象,它将失败并抛出错误。有没有办法确保function A(){} A.prototype = "Foo bar"; new A() instanceof A; // TypeError: Function has non-object prototype 'Foo bar' in instanceof check 不会失败?

instanceof

typeof new A().constructor.prototype === "object"

显然不起作用。

4 个答案:

答案 0 :(得分:1)

使用try/catch来捕获错误;

function isItA(obj) {
  try {
    return obj instanceof A;
  } catch (e) {
    return false; //
  }
}

function A() {}
A.prototype = "Foo bar";
function B() {}
B.prototype = "Baz Quux";
console.log(isItA(new A()));
console.log(isItA(new B()));

答案 1 :(得分:1)

错误说A.prototype需要是一个对象,所以你应该检查一下:

function isObject(x) {
    return x != null && (typeof x == "object" || typeof x == "function");
}

isObject(A.prototype)并非你所能做的就是断言instanceof来电不会被抛出。按照规范,你应该测试

function allowsInstanceCheck(C) {
    try {
        if (!isObject(C)) return false;
        var m = C[Symbol.hasInstance];
        if (m != null) return typeof m == "function";
        if (typeof C != "function") return false;
        return isObject(C.prototype);
    } catch (e) {
        // any of the property accesses threw
        return false;
    }
}

答案 2 :(得分:1)

也许不是一个真正的答案,而是一个有趣的结论。

当一个函数作为构造函数被调用时,如果它的 prototype 属性不是一个Object,那么新实例被赋予 intrinsicDefaultProto 作为它的{{ 1}}如GetPrototypeFromConstructor中所述。

在创建新实例的过程中, intrinsicDefaultProto 会传递 fallbackProto 的值,这似乎是(至少在Firefox中) Object.prototype中

由于 Object.prototype 构造函数属性是Object,因此测试实例的构造函数属性是否引用候选对象不会起作用任

&#13;
&#13;
[[Prototpye]]
&#13;
&#13;
&#13;

因此 instanceof 失败的情况可能会导致程序设计或实现中出现更严重的问题。隐藏这些错误似乎不是一个好主意(除非意图将陷阱留在代码中以供将来的维护者发现)。

答案 3 :(得分:0)

我使用:typeof o.prototype ===“ function” && o instanceof f