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

コンストラクターとは何ですか? JavaScriptのコンストラクタの詳しい説明

青灯夜游
リリース: 2022-08-04 15:24:16
転載
2875 人が閲覧しました

プロトタイプとプロトタイプ チェーンの基礎として、まずコンストラクターとその実行プロセスを理解することは、プロトタイプとプロトタイプ チェーンの知識をよりよく学ぶのに役立ちます。この記事では、JavaScript のコンストラクターについて詳しく説明し、コンストラクターを使用して js オブジェクトを作成する方法を紹介します。

コンストラクターとは何ですか? JavaScriptのコンストラクタの詳しい説明

#1. コンストラクターとは何ですか?

通常の関数を使用してクラス オブジェクトを作成する場合、その関数はコンストラクター、またはコンストラクターと呼ばれます。 (理解を容易にするために、JavaScript でのコンストラクターの作成は、他の言語でのクラスの作成と理解できます。目的は、これを使用して new を通じてオブジェクトをインスタンス化することです)

function Person(){
//...
}
//当做普通函数调用
var obj=Person();

//构造函数调用
	 var obj=new Person();
ログイン後にコピー

の特徴コンストラクター :

  • 標準の記述に関して、私たちはコンストラクター名の最初の文字を大文字にすることに慣れています。

  • new を通じてオブジェクトを作成します。

  • 内部にreturnを書かなくても戻り値があり、返されるのはオブジェクトです。

#コンストラクターを使用して js オブジェクトを作成する

  • コンストラクターはオブジェクトを作成します (メソッドはコンストラクター、欠点: コンストラクターが実行されるたびにメソッドが作成されます。)

  • 	  function Person(name,age,gender){
                this.name=name;
                this.age=age;
                this.gender=gender;
                // 方法写在里面
                this.sayName=function(){
                     console.log(this.name);
                 }      
              }
        
              function Dog(name,age){
                  this.name=name;
                  this.age=age;
              }
             
              var obj=new Person("张三",18,"男");
              var obj1=new Person("李四",16,"男");
              
              var dog=new Dog("乐乐",2);
              obj.sayName();
              obj1.sayName();
              
              console.log(obj);
              console.log(obj1);
              console.log(dog);
    ログイン後にコピー
  • コンストラクターはオブジェクトを作成します (メソッドはコンストラクターの外に記述されます)。 、欠点: メソッドはグローバル メソッドであるため、グローバルを汚染します。)

    #
    	   function Person(name,age,gender){
                this.name=name;
                this.age=age;
                this.gender=gender;
                this.sayName=fun;   //方法写在外面
              }
        	 function fun(){
                console.log(this.name);
            }
              function Dog(name,age){
                  this.name=name;
                  this.age=age;
              }
              
              var obj=new Person("张三",18,"男");
              var obj1=new Person("李四",16,"男");
              
              var dog=new Dog("乐乐",2);
              obj.sayName();
              obj1.sayName();
              
              console.log(obj);
              console.log(obj1);
              console.log(dog);
    ログイン後にコピー
#コンストラクター関数はオブジェクト変換を作成します (メソッドはプロトタイプ オブジェクトを通じて作成されます)
  • プロトタイプ オブジェクト: プロトタイプ
作成する関数ごとに、パーサーはプロトタイプ属性を関数に追加します。

コンストラクターのプロトタイプ オブジェクトへのポイント。__proto__ を通じてこのプロパティにアクセスできます。

Constructor.prototype.xxx、xxx は変数またはメソッドです。実行プロセス中、最初にオブジェクト内のメソッドまたは変数を検索し、見つからない場合はプロトタイプ内で検索します。

	  function Person(name,age,gender){
            this.name=name;
            this.age=age;
            this.gender=gender;
          }
          function Dog(name,age){
              this.name=name;
              this.age=age;
          }
          
        /*为person添加统一的方法, 到原型对象中*/
        Person.prototype.sayName=function(){
            console.log(this.name);
        }
          var obj=new Person("张三",18,"男");
          var obj1=new Person("李四",16,"男");
          
          var dog=new Dog("乐乐",2);
          obj.sayName();
          obj1.sayName();
          
          console.log(obj);
          console.log(obj1);
          console.log(dog);
ログイン後にコピー

実行結果:

コンストラクターとは何ですか? JavaScriptのコンストラクタの詳しい説明2. コンストラクターを使用する理由

各概念を学ぶには、それが何であるかだけでなく、それがなぜ、どのような問題を解決するのかを知る必要があります。

たとえば、1 年生のクラスの各生徒の個人情報を入力したい場合は、次のようなオブジェクトを作成できます。

var p1 = { name: 'zs', age: 6, gender: '男', hobby: 'basketball' };
var p2 = { name: 'ls', age: 6, gender: '女', hobby: 'dancing' };
var p3 = { name: 'ww', age: 6, gender: '女', hobby: 'singing' };
var p4 = { name: 'zl', age: 6, gender: '男', hobby: 'football' };
// ...
ログイン後にコピー
上記と同様、私たち生徒一人ひとりの情報をオブジェクトとして扱うことができます。しかし、意味のないコードを繰り返し書いていることがわかります。名前、年齢、性別、趣味など。このクラスに生徒が 60 人いる場合、60 回書かなければなりません。

このとき、コンストラクターの利点が反映されます。各生徒は名前、性別、趣味などの属性を持っていますが、それらはすべて異なることがわかったので、これらの属性をコンストラクターのパラメーターとして渡します。また全員1年生なので年齢も基本的には6歳なので、特別な事態に遭遇した場合にはメモに書いて個別に対応することができます。この時点で、次の関数を作成できます。

function Person(name, gender, hobby) {
    this.name = name;
    this.gender = gender;
    this.hobby = hobby;
    this.age = 6;
}
ログイン後にコピー

上記の関数を作成した後、 new キーワードを使用してそれを呼び出すことができます。つまり、コンストラクターを使用してオブジェクトを作成できます。

var p1 = new Person('zs', '男', 'basketball');
var p2 = new Person('ls', '女', 'dancing');
var p3 = new Person('ww', '女', 'singing');
var p4 = new Person('zl', '男', 'football');
// ...
ログイン後にコピー

この時点で、オブジェクトの作成が非常に便利になることがわかります。したがって、コンストラクターをカプセル化するプロセスはより面倒になりますが、一度カプセル化が成功すると、オブジェクトの作成が非常に簡単になるため、コンストラクターを使用します。

オブジェクト リテラルを使用して同じ型の一連のオブジェクトを作成する場合、これらのオブジェクトはいくつかの類似した特性 (プロパティ) や動作 (メソッド) を持つ場合があります。このとき、大量の繰り返しコードが生成されます。コンストラクターを使用すると、

コードの再利用

を実現できます。

3. コンストラクターの実行プロセス

まず、いくつかの基本的な概念について説明します。
function Animal(color) {
 this.color = color;
}
ログイン後にコピー

関数を作成した時点では、それがコンストラクターであるかどうかはわかりません。上記の例のように関数名が大文字であっても、それがコンストラクターであるかどうかはわかりません。関数が new キーワードを使用して呼び出された場合にのみ、それがコンストラクターであると言えます。次のようになります。

var dog = new Animal("black");
ログイン後にコピー

以下では、コンストラクターの実行プロセス、つまり new キーワードを使用して呼び出された場合についてのみ説明します。

引き続き、上記の人物を例として取り上げます。

function Person(name, gender, hobby) {
 this.name = name;
 this.gender = gender;
 this.hobby = hobby;
 this.age = 6;
}

var p1 = new Person('zs', '男', 'basketball');
ログイン後にコピー

この時点で、コンストラクターには次の実行プロセスがあります:

1) new キーワードを使用して呼び出されると、新しいメモリ空間が作成され、Animal のインスタンスとしてマークされます。

2) 関数本体内の this はメモリを指します

上記の 2 つの手順を通じて、この結論を導き出すことができます。

var p2 = new Person('ls', '女', 'dancing');  // 创建一个新的内存 #f2
var p3 = new Person('ww', '女', 'singing');  // 创建一个新的内存 #f3
ログイン後にコピー

インスタンスが作成されるたびに、新しいメモリ空間(#f2、#f3)が作成されます。#f2が作成されると、関数本体内のthisは#f2を指し、#f3が作成されます。このとき、関数本体内のthisは#f3を指します。

3) 执行函数体内的代码
通过上面的讲解,你就可以知道,给 this 添加属性,就相当于给实例添加属性。

4)默认返回 this

由于函数体内部的this指向新创建的内存空间,默认返回 this ,就相当于默认返回了该内存空间,也就是上图中的 #f1。此时,#f1的内存空间被变量p1所接受。也就是说 p1 这个变量,保存的内存地址就是 #f1,同时被标记为 Person 的实例。

以上就是构造函数的整个执行过程。

4、构造函数的返回值

构造函数执行过程的最后一步是默认返回 this 。言外之意,构造函数的返回值还有其它情况。下面我们就来聊聊关于构造函数返回值的问题。

1)没有手动添加返回值,默认返回 this

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

var p1 = new Person1();
ログイン後にコピー

按照上面讲的,我们复习一遍。首先,当用 new 关键字调用时,产生一个新的内存空间 #f11,并标记为 Person1 的实例;接着,函数体内部的 this 指向该内存空间 #f11;执行函数体内部的代码;由于函数体内部的this 指向该内存空间,而该内存空间又被变量 p1 所接收,所以 p1 中就会有一个 name 属性,属性值为 ‘zhangsan’。

p1: {
 name: 'zhangsan'
}
ログイン後にコピー

2)手动添加一个基本数据类型的返回值,最终还是返回 this

function Person2() {
 this.age = 28;
 return 50;
}

var p2 = new Person2();
console.log(p2.age);   // 28
p2: {
 age: 28
}
ログイン後にコピー

如果上面是一个普通函数的调用,那么返回值就是 50。

3)手动添加一个复杂数据类型(对象)的返回值,最终返回该对象

直接上例子

function Person3() {
 this.height = '180';
 return ['a', 'b', 'c'];
}

var p3 = new Person3();
console.log(p3.height);  // undefined
console.log(p3.length);  // 3
console.log(p3[0]);      // 'a'
ログイン後にコピー

再来一个例子

function Person4() {
  this.gender = '男';
  return { gender: '中性' };
}

var p4 = new Person4();
console.log(p4.gender);  // '中性'
ログイン後にコピー

5、构造函数首字母必须大写吗?

大小写都可以

6、不用new关键字,直接运行构造函数,是否会出错?

如果不会出错,那么,用new和不用new调用构造函数,有什么区别?

1)使用new操作符调用函数

例子:

function Person(name){
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
}

var person1 = new Person('nicole');
person1.say(); // "I am nicole"
ログイン後にコピー

用new调用构造函数,函数内部会发生如下变化:

创建一个this变量,该变量指向一个空对象。并且该对象继承函数的原型;
属性和方法被加入到this引用的对象中;
隐式返回this对象(如果没有显性返回其他对象)
用伪程序来展示上述变化:

function Person(name){
  // 创建this变量,指向空对象
  var this = {}; 
  // 属性和方法被加入到this引用的对象中
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
  // 返回this对象
  return this;
}
ログイン後にコピー

可以看出,用new调用构造函数,最大特点为,this对象指向构造函数生成的对象,所以,person1.say()会返回字符串: “I am nicole”。

小贴士:如果指定了返回对象,那么,this对象可能被丢失。

function Person(name){
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
  var that = {};
  that.name = "It is that!";
  return that;
}

var person1 = new Person('nicole');
person1.name; // "It is that!"
ログイン後にコピー

2)直接调用函数

如果直接调用函数,那么,this对象指向window,并且,不会默认返回任何对象(除非显性声明返回值)。

还是拿Person函数为例,直接调用Person函数:

var person1 = Person('nicole');
person1; // undefined
window.name; // nicole
ログイン後にコピー

可见,直接调用构造函数的结果,并不是我们想要的。

3)小结

为了防止因为忘记使用new关键字而调用构造函数,可以加一些判断条件强行调用new关键字,代码如下:

function Person(name){
  if (!(this instanceof Person)) {
    return new Person(name);
  }
  this.name = name;
  this.say = function(){
    return "I am " + this.name;
  }
}

var person1 = Person('nicole');
console.log(person1.say()); // I am nicole
var person2 = new Person('lisa');
console.log(person2.say()); // I am lisa
ログイン後にコピー

【相关推荐:javascript学习教程

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

ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート