>  기사  >  웹 프론트엔드  >  JavaScript 기본 지식 공유 및 기능화_기본 지식

JavaScript 기본 지식 공유 및 기능화_기본 지식

WBOY
WBOY원래의
2016-05-16 15:15:52968검색
1.对象适合于收集和管理数据,容易形成树型结构。
Javascript包括一个原型链特性,允许对象继承另一对象的属性。正确的使用它能减少对象的初始化时间和内存消耗。
2.函数它们是javascript的基础模块单元,用于代码复用、信息隐藏和组合调用。函数用于指定对象的行为。一般来说,编程就是将一组需求分解成一组函数和数据结构的技能。
3.模块我们可以使用函数和闭包来构造模块。模块是一个提供接口却隐藏实现状态和实现的函数或对象。

1. 사용자 정의 유형-생성자 모드(의사 클래스 모드)

클래스 기반 시스템에서는 클래스를 사용하여 객체가 무엇인지 설명함으로써 객체를 정의합니다. 건축이 계급 기반 시스템이라면 건축가는 먼저 집의 청사진을 그린 다음 그 청사진에 따라 집을 지을 것입니다.

상속을 구현하기 위해 사용자 정의 유형 패턴을 사용할 때 매개변수를 생성자에 전달한 다음 인스턴스 객체에 매개변수를 마운트하기만 하면 됩니다. 인스턴스 개체의 다른 메서드는 매개 변수를 전달할 필요가 없습니다. 매개 변수는 인스턴스 개체가 호출하는 메서드 내에서 이를 통해 액세스할 수 있기 때문입니다. 인스턴스의 이 객체에 마운트된 변수를 인스턴스 변수라고 합니다.

구성-상속

function Person (name, age, job) {
  // 实例变量
  this.name = name;
  this.age = age;
  this.job = job;
}
Person.prototype.sayName = function () {
  alert(this.name);
}

var person1 = new Person('Nicholas', 29, 'Software Engineer');
var person2 = new Person('Greg', 27, 'Doctor');
function SuperType (name) {
  this.name = name;
  this.colors = ['red','blue', 'green'];
}

SuperType.prototype.sayName = function () {
  console.log(this.name);
}

function SubType (name, age) {
  // 继承属性
  SuperType.call(this,name);
  this.age = age;
}

// 继承方法
SubType.prototype = new SuperType();

SubType.prototype.sayAge = function () {
  console.log(this.age)
}

var instance1 = new SubType('Nicholas', 29);
instance1.colors.push('black')
console.log(instance1.colors);
instance1.sayName();
instance1.sayAge();

var instance2 = new SubType('Greg', 27)
console.log(instance2.colors);
instance2.sayName();
instance2.sayAge();

상속 속성과 상속 메소드 측면에서 슈퍼클래스 생성자를 두 번 호출했는데, 서브클래스 생성자의 프로토타입을 생성하기 위해 new를 통해 슈퍼클래스 생성자를 호출할 때, 서브클래스 생성자의 프로토타입 객체에 문제가 생겼습니다. 슈퍼클래스 생성자의 인스턴스이므로 슈퍼클래스 생성자의 인스턴스 객체 this에도 속성이 추가되지만 값은 정의되지 않습니다. 즉, 슈퍼클래스 생성자 함수는 서브클래스 변환기를 변경하기 위해 new를 통해 호출됩니다. 하위 클래스 생성자의 프로토타입이 사용되면 하위 클래스 생성자의 프로토타입에 중복 속성이 있게 됩니다. 이로 인해 낭비가 발생합니다. 실제로 우리에게 필요한 것은 하위 클래스 생성자의 프로토타입이 슈퍼클래스 생성자 프로토타입의 메서드를 상속할 수 있다는 것입니다. 그래서 우리에게 필요한 것은

1. 하위 클래스 생성자 프로토타입 객체를 만듭니다.

2. 이 하위 클래스 생성자의 프로토타입은 슈퍼클래스 생성자의 프로토타입에서 상속됩니다.

3. 1에서 서브클래스 생성자의 프로토타입 객체를 다시 작성했으므로, 즉 프로토타입 객체를 다시 생성했기 때문에 새로 생성된 프로토타입 객체에 생성자 속성을 추가하고 서브클래스 생성자 함수에 할당해야 합니다.

위의 코드를 다음과 같이 다시 작성하세요.

생성자 속성 정보: 이 속성은 생성자 함수의 프로토타입에서만 사용할 수 있으며 다시 작성된 프로토타입 객체에는 기본적으로 생성자 속성이 없습니다.

기생조합-상속

function inheritPrototype (subType,superType) {
  var prototype = Object.creat(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
};

function SuperType (name) {
  this.name = name;
  this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {
  console.log(this.name);
}
function SubType(name, age) {
  //继承属性
  SuperType.call(this,name);
  this.age = age;
}
//继承方法
inheritPrototype(SubType,SuperType);
SubType.prototype.sayAge = function () {
  console.log(this.age);
}

var instance = new SubType();

소위 프로토타입 작업 세부 정보를 숨김으로써 이제 덜 이상해 보입니다. 그런데 정말 뭔가를 발견하셨나요?
비공개 환경은 없으며 모든 속성은 공개됩니다. 상위 클래스 메서드에 액세스할 수 없습니다. 디버깅이 어려움

2. 프로토타입

순수한 프로토타입 패턴에서는 클래스를 포기하고 대신 객체에 집중합니다. 프로토타입 기반 상속은 클래스 기반 상속보다 개념적으로 더 간단합니다. 새 객체는 이전 객체의 속성을 상속할 수 있습니다. 유용한 개체를 구성하는 것부터 시작한 다음 해당 개체와 유사한 개체를 더 많이 구성할 수 있습니다. 이렇게 하면 애플리케이션을 일련의 중첩된 추상 클래스로 나누는 분류 프로세스를 완전히 피할 수 있습니다
프로토타입 기반 시스템에서는 우리가 원하는 해당 유형의 모든 개체처럼 보이는 개체를 만든 다음 JavaScript 엔진에 더 많은 개체를 원한다고 알립니다. 건축이 프로토타입을 기반으로 한다면 건축가는 먼저 집을 지은 다음 모든 집을 이런 모양으로 지을 것입니다.

Object.creat() 메소드는 new 연산자의 대안으로 JavaScript 객체를 생성할 때 프로토타입 기반의 느낌을 더할 수 있습니다.

function myMammal = {
  name : 'Herb the Mammal',
  get_name : function () {
    return this.name;
  },
  says : function () {
    return this.saying || '';
  }
}

var myCat = Object.create(myMammal);
myCat.name = 'Henrietta';
myCat.saying = 'meow';
myCat.purr = function (n) {
  var i, s = '';
  for (i = 0;i < n; i += 1) {
    if(s) {
      s += '-'
    }
    s += 'r';
  }
  return s;
}

myCat.get_name = function () {
  return this.says + ' ' + this.name + this.says;
}

这是一种"差异化继承"。通过定制一个新的对象,我们指明它与所基于的基本对象的区别。
有时候,它对某些数据结构继承于其他数据结构的情形非常有用。

3.函数化--工厂模式

在伪类模式里,构造器函数Cat不得不重复构造器Mammal已经完成的工作。在函数化模式中那不再需要了,因为构造器Cat将会调用构造器Mammal,让Mammal去做对象创建中的大部分工作,所有Cat只关注自身的差异即可。
函数化模式有很大的灵活性。它相比伪类模式不仅带来的工作更少,还让我们得到更好的封装和信息隐藏,以及访问父类方法的能力。

如果我们用函数化得样式去创建对象,并且该对象的所有方法都不用this或that,那么该对象就是持久性的。一个持久性的对象就是一个简单功能函数的集合。

私有变量:任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数外部访问这些变量。

闭包

闭包是阻止垃圾回收器将变量从内存中移除的方法,使的在创建变量的执行环境的外面能够访问到该变量。
请记住:闭包由函数创建。每次调用函数会创建一个唯一的执行环境对象。函数执行完后,执行对象就会被丢弃,除非调用者引用了它。当然,如果函数返回的是数字,就不能引用函数的执行环境对象。但是如果函数返回的是一个更复杂的结构,像是函数、对象或者数组,将返回值保存到一个变量上,就创建了一个对执行环境的引用。

Function.prototype.method = function (name,func) {
  this.prototype[name] = func;
  return this; 
}
// 工厂mammal函数
var mammal = function (spec) {
  var that = {};

  that.get_name = function () {
    return spec.name;
  }
  that.says = function (spec) {
    return spec.saying || '';
  } 

  return that;
}

// 工厂cat函数(基于mammal的函数)
var cat = function (spec) {
  spec.saying = spec.saying || 'meow';
  var that = mammal(spec);
  that.purr = function (n) {
    var i, s = '';
    for (i = 0; i < n; i += 1) {
      if(s) {
        s += '-';
      }
      s += 'r';
    }
  }
  that.get_name = function () {
    return that.says() + ' ' + spec.name + ' ' + that.says();
  }
  return that;
}

// 创建myCat对象
var myCat = cat({name: 'Henrietta'});

Object.method('superior',function (name) {
  var that = this,
    method = that[name];
  return function () {
    return method.apply(that, arguments)
  }
})

// 工厂coolcat函数(基于cat函数)
var coolcat = function (spec) {
  var that = cat(spec),
    super_get_name = that.superior('get_name');
  that.get_name = function (n) {
    return 'like ' + super_get_name() + ' baby';
  }
  return that;
}

var myCoolCat = coolcat({name : 'Bix'});

var name = myCoolCat.get_name();

函数化模块模式有很大的灵活性。它相比构造函数模式不仅带来的工作更少,还让我们得到更好的封装休息和隐藏,以及访问父类方法的能力。如果对象的所有状态都是私有的,那么该对象就成为一个"防伪(tamper-proof)"对象。该对象的属性是可以被替换或者删除,当该对象的完整性不会受到损坏。我们用函数式的样式创建一个对象,并且该对象的所有方法都不使用this或者that,那么该对象就是持久性对象。一个持久性对象,就是一个简单的函数功能的集合。
一个持久性的对象不会被入侵。访问一个持久性的对象时,除非有方法授权,否则攻击者不会访问对象的内部状态。

模块模式

前面的模式是用于 自定义类型创建私有变量和特权方法的。而道格拉斯所说的模块模式则是为 单例创建私有变量和特权方法。所谓单例指的就是只有一个实例的对象。(就是用对象字面量表示法创建的对象)

var singleton = function () {
  // 私有变量和函数
  var privateVariable = 10;

  function privateFunction () {
    return false;
  }
  //特权/公有方法和属性
  return {
    publicProvperty: true;

    publicMethod: function () {
      privateVariable++;
      return privateFunction();
    }
  }
}

从本质上讲,这个对象字面量定义的是单例的公共接口。这种模式在需要对单例进行某些初始化,同时又需要维护其私有变量时非常有用。简言之,如果必须创建一个对象并以某些数据对其进行初始化,同时还要公开一些能够访问这些私有数据的方法。

增强的模块模式

这种增强的模块模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性和方法对其加以增强的例子。

var singleton = function () {
  // 私有变量和函数
  var privateVariable = 10;

  function privateFunction () {
    return false
  }
  // 创建对象
  var object = new CustomType();

  // 添加特权/公有属性和方法
  object.publicProperty = true;
  object.publicMethod = function () {
    privateVariable++;
    return privateFunction();
  }

  return object;
}()

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.