ホームページ >ウェブフロントエンド >jsチュートリアル >JavaScriptコンストラクターの詳しい説明

JavaScriptコンストラクターの詳しい説明

小云云
小云云オリジナル
2018-02-23 16:06:121762ブラウズ

コンストラクターをよく理解することが、JavaScript 言語を習得するための鍵です。 JavaScript には他の言語とは異なり、class キーワードがありませんが、function によく似たコンストラクターがあることは誰もが知っています。この記事では、JavaScript コンストラクターがオブジェクトを構築する方法を詳しく学びましょう。 class关键字,但是它有跟function非常相似的构造函数。这篇文章我们一起来详细地了解JavaScript构造函数如何构造对象。

构造函数跟普通函数非常相似,但是我们通过new关键字来使用它们。主要有两种类型的构造函数,native构造函数(Array,Object)它们可以在执行环境中自动生成,还有自定义的构造函数,你可以定义自己的方法和属性。

当你想要创建很多相似的对象(拥有相同的属性和方法)的时候,使用构造函数是非常有效的。大部分程序员都遵循公约,使用大写字母开头来将构造函数和普通函数区分开。看看下面的代码。

function Book() { 
    // unfinished code} 
var myBook = new Book();

最后一行代码创建了一个Book对象,并把它赋值给变量;这样完成之后,即使Book构造器没有做任何操作,myBook也是Book实例。正如你看到的,除了首字母大写和使用new关键字之外,构造函数和普通函数并没有什么区别。

判断实例的类型

判断某个对象是否为某种实例,我们可以使用instanceof操作符:

myBook instanceof Book    // => truemyBook instanceof String  // => false

注意:如果右边不是一个函数的实例,那么将会报错:

myBook instanceof {}; // => TypeError: invalid 'instanceof' operand ({})

另一种方法是使用constructor属性,所有对象实例都有一个constructor属性,这个属性指向创建它的构造函数。

myBook.constructor == Book;   // => true

就像myBookconstructor指向Book一样。 所有对象都从它们的原型上继承了constructor这个属性:

var s = new String("text");
s.constructor === String;      // => true"text".constructor === String; // => truevar o = new Object();
o.constructor === Object;      // => truevar o = {};
o.constructor === Object;      // => truevar a = new Array();
a.constructor === Array;       // => true[].constructor === Array;      // => true

尽管使用constructor可以用来检测实例类型,但是建议还是使用instanceof方法。因为constructor属性是可以被重写的..用起来不太靠谱。

自定义构造函数

构造函数就像饼干印模。同一印模制作出来的,都是同一个diao样(男人没一个好东西也是这个道理)。

function Book(name, year) {    this.name = name;    this.year = '(' + year + ')';
}

Book构造器需要两个参数,当使用new关键字构造对象时,会把两个形参传给Book对象的nameyear

var firstBook = new Book("Pro AngularJS", 2014);var secondBook = new Book("Secrets Of The JavaScript Ninja", 2013); 
var thirdBook = new Book("JavaScript Patterns", 2010);

console.log(firstBook.name, firstBook.year);           
console.log(secondBook.name, secondBook.year);           
console.log(thirdBook.name, thirdBook.year);

如你所见,我们可以通过传不同参数,快速创建另一本书。JavaScript的Array(),Date()也是这个道理。

Object.defineProperty 方法

Object.defineProperty 方法可以在构造器中被使用来配置属性。

function Book(name) { 
    Object.defineProperty(this, "name", { 
        get: function() { 
            return "Book: " + name;       
        },        
        set: function(newName) {            
            name = newName;        
        },               
        configurable: false     
    }); 
}var myBook = new Book("Single Page Web Applications");
console.log(myBook.name);    // => Book: Single Page Web Applications// we cannot delete the name property because "configurable" is set to falsedelete myBook.name;    
console.log(myBook.name);    // => Book: Single Page Web Applications// but we can change the value of the name propertymyBook.name = "Testable JavaScript";
console.log(myBook.name);    // => Book: Testable JavaScript

上面的代码中是调用了祖先的方法。它提供了gettersetter接口。getter方法负责返回封装的值,setter方法接受参数,并把值赋给属性。当我们在某个属性上操作存取时,调用的就是这两个方法。通过配置configurable,我们可以设置该值能否被删除。

对象字面量表示法是首选的构造函数

JavaScript语言九种内建的构造器:Object(), Array(), String(), Number(), Boolean(), Date(), Function(), Error() 以及 RegExp()。当我们需要创建这些值的时候,我们可以自由选择使用字面量或者构造器。但是相同情况下,字面量对象不仅易读,而且运行速度更快,因为他们可以在解析的时候被优化。所以当你需要使用简单对象的时候就使用字面量吧。

// a number object// numbers have a toFixed() methodvar obj = new Object(5);
obj.toFixed(2);     // => 5.00// we can achieve the same result using literalsvar num = 5;
num.toFixed(2);     // => 5.00// a string object// strings have a slice() method var obj = new String("text");
obj.slice(0,2);     // => "te"// same as abovevar string = "text";string.slice(0,2);  // => "te"

使用new关键字是必不可少的

记得使用构造器的时候要用new关键字,如果你不小心忘记了,那么构造器中的this指向的是global对象(浏览器中默认为window)。

function Book(name, year) {
    console.log(this);    this.name = name;    this.year = year;
}var myBook = Book("js book", 2014);  
console.log(myBook instanceof Book);  
console.log(window.name, window.year);var myBook = new Book("js book", 2014);  
console.log(myBook instanceof Book);  
console.log(myBook.name, myBook.year);

上面的代码运行结果如下所示:

如果是在严格模式下,上面的代码将会抛出错误,因为严格模式不允许我们不使用new关键字调用构造器。

适用范围更高的构造器

为了解决可能会忘记使用new关键字的风险,我们可以通过判断this

コンストラクターは通常の関数に非常に似ていますが、new キーワードを通じて使用します。コンストラクターには主に 2 つのタイプがあります。1 つは実行環境で自動的に生成できる native コンストラクター (ArrayObject) です。もう 1 つは実行環境で自動的に生成できるコンストラクターです。定義されたコンストラクターを使用すると、独自のメソッドとプロパティを定義できます。

コンストラクターの使用は、(同じプロパティとメソッドを持つ) 類似したオブジェクトを多数作成する場合に非常に効果的です。ほとんどのプログラマーは、コンストラクターと通常の関数を区別するために大文字を使用するという規則に従っています。以下のコードを見てください。 🎜
function Book(name) { 
    if (!(this instanceof Book)) { 

        // the constructor was called without "new".        return new Book(name);
    } 
}
🎜 コードの最後の行は、Book オブジェクトを作成し、これが完了した後、Book コンストラクターが何も行わない場合でも、 オブジェクトを変数に割り当てます。 >myBook Book のインスタンスでもあります。ご覧のとおり、最初の文字を大文字にすることと new キーワードを使用することを除けば、コンストラクターと通常の関数の間に違いはありません。 🎜

インスタンスのタイプを決定する

🎜 オブジェクトが特定のタイプのインスタンスであるかどうかを決定するには、instanceof 演算子を使用できます: 🎜
function Book(name, year) { 
    if (!(this instanceof Book)) { 
        return new Book(name, year);
    }    this.name = name;    this.year = year;
}var person1 = new Book("js book", 2014);var person2 = Book("js book", 2014);
console.log(person1 instanceof Book);    // => trueconsole.log(person2 instanceof Book);    // => true
🎜注: If 右側が関数のインスタンスではない場合、エラーが報告されます: 🎜rrreee🎜もう 1 つの方法は、constructor 属性を使用することです。すべてのオブジェクト インスタンスには constructor があります。 属性。コンストラクターの作成を指します。 🎜rrreee🎜 myBookconstructorBook を指しているのと同じです。 すべてのオブジェクトは、プロトタイプから constructor プロパティを継承します: 🎜rrreee🎜 constructor を使用してインスタンス タイプを検出できますが、 instanceof を使用することをお勧めします。 >方法です。 constructor 属性はオーバーライドできるため、使用するのはあまり信頼できません。 🎜

カスタム コンストラクター

🎜 コンストラクターはクッキー スタンパーのようなものです。それらはすべて同じ印象から作られています(男性が良いものを持っていないのと同じ理由)。 🎜rrreee🎜 Book コンストラクターには 2 つのパラメーターが必要です。 new キーワードを使用してオブジェクトを構築する場合、2 つの仮パラメーターは Book に渡されます。オブジェクトの名前。 🎜rrreee🎜🎜🎜ご覧のとおり、さまざまなパラメータを渡すことで、すぐに別のものを作成できます。本。 JavaScript の Array()Date() にも同じことが当てはまります。 🎜

Object.defineProperty メソッド

🎜Object.defineProperty メソッドは、コンストラクターでプロパティを構成するために使用できます。 🎜rrreee🎜上記のコードは祖先メソッドを呼び出します。 getter インターフェイスと setter インターフェイスを提供します。 getter メソッドはカプセル化された値を返す役割を果たし、setter メソッドはパラメータを受け取り、その値をプロパティに割り当てます。特定の属性に対してアクセスを操作する場合、これら 2 つのメソッドが呼び出されます。 configurable を設定することで、値を削除できるかどうかを設定できます。 🎜

オブジェクト リテラル表現が優先コンストラクターです

🎜 JavaScript 言語には 9 つの組み込みコンストラクターがあります: Object()Array()String()Number()Boolean()Date()Function( ) code>、<code>Error()、および RegExp()。これらの値を作成する必要がある場合は、リテラルまたはコンストラクターを自由に使用できます。しかし、同じ状況下では、リテラル オブジェクトは読みやすいだけでなく、解析中に最適化できるため高速になります。したがって、単純なオブジェクトを使用する必要がある場合はリテラルを使用してください。 🎜rrreee

new キーワードの使用は必須です

🎜 コンストラクターを使用するときは、new キーワードを忘れずに使用してください。this global オブジェクトを指します (デフォルトはブラウザの window です)。 🎜rrreee🎜上記のコードを実行した結果は次のとおりです: 🎜🎜🎜🎜厳密モードの場合、厳密モードでは new キーワードを使用せずにコンストラクターを呼び出すことができないため、上記のコードはエラーをスローします。 🎜

より適用範囲の高いコンストラクタ

🎜 new キーワードの使用を忘れるリスクを解決するために、this より高いスコープを持つコンストラクター。 🎜rrreee🎜 このコードを追加すると、コンストラクターを「不正に」使用できるようになります。 🎜<pre class="javascript">function Book(name, year) { if (!(this instanceof Book)) { return new Book(name, year); } this.name = name; this.year = year; }var person1 = new Book(&quot;js book&quot;, 2014);var person2 = Book(&quot;js book&quot;, 2014); console.log(person1 instanceof Book); // =&gt; trueconsole.log(person2 instanceof Book); // =&gt; true</pre><p>很多内建的构造器都是这么做的。通过判断<code>this是否为当前类型。如果程序员忘记加new关键字,那么我们就返回一个通过new出来的对象。

结论

JavaScript没有类这种说法(但是它可以使面向对象的),所以对于习惯了使用类的程序员来说是种困惑。当然JavaScript的构造函数跟普通函数没什么区别,只是通过new关键字生成出来而已。如果我们需要”印饼干”的话,它就非常有用了。

相关推荐:

JavaScript构造器模式实例分析

什么是构造器?引用类型是什么?

有关查询构造器的文章推荐7篇

以上がJavaScriptコンストラクターの詳しい説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。