Home首页 prototype原型 - xiaojiandong/blogAndResourceCollect GitHub Wiki

Welcome to the blogAndResourceCollect wiki!

js原型prototype的实现

原型git链接 资料链接

 <script type="text/javascript">
  // length属性
  function check(args){
    var actualLen = args.length; // 实参的真实个数
    var expectedLen = args.callee.length; // 期望的实参个数
    if(actualLen != expectedLen){
      throw Error('实参真实个数actualLen: ' + actualLen + '; 实参期望个数: ' + expectedLen);
    }else{
      console.log('实参个数和期望实参个数一致');	
    }
  };
  function f(x,y,z){
  	check(arguments); // 检查实参个数和期望实参个数是否一致
  	return x + y + z; // 再执行后续逻辑
  };
  f(2,3,4);
  // 链接 : http://www.cnblogs.com/xiaouisme/archive/2012/09/17/2688298.html
  // prototype原型,作用:一个给类的对象添加方法的方法
  // js中允许的类型有Array, Boolean, Date, Enumerator, Error, Function, Number, Object, RegExp, String
  // 1. 可以在类型上使用proptotype来为类型添加行为。这些行为只能在类型的实例上体现。
  function classOne(){

  };
  classOne.prototype.attr1 = '1.1 这是classOne类的 原型 的属性attr1'; // 为classOne这个类添加原型属性attr1
  classOne.prototype.attrFn = function(){ // 为classOne这个类添加原型方法attrFn
    alert('1.2 这是classOne类的 原型 的方法attrFn');
  }; 
  var c1 = new classOne();
  alert(c1.attr1); // 可以调用原型的attr1属性
  c1.attrFn(); // 调用原型的attrFn方法

  console.log('===============================');
  
  // 2. 在实例上不能使用prototype,否则会发生编译错误
  /*
  var o1 = new Object(); // 已经创建了o1实例
  o1.prototype.oAttr = 10; // 编译错误,因为o1是实例
  o1.prototype.oAttrFn = function(){ // 编译错误
     console.log('o1实例的oAttrFn方法是错误的');
  };
  */

  // 3. 可以为类型定义静态的属性和方法,在类型上直接调用即可
  Object.attrProperty = '3.1 这是Object这个类的静态属性attrProperty,可以直接在类型上调用';
  Object.objectFn = function(){
      console.log('3.2 这是Object这个类的静态方法objectFn,可以直接在类型上调用');
  };
  console.log(Object.attrProperty);
  Object.objectFn();

  // 4. 实例不能调用类型的静态属性或方法,否则发生对象未定义错误
  /*
  String.strPrototype = '4.1 这是String这个类型的静态属性strPrototype,不能被实例调用';
  String.stringFn = function(){
     console.log('4.2 这是String这个类型的静态方法stringFn 不能被实例调用')
  };
  var str1 = new String();
  console.log(str1.strPrototype); // undefined
  str1.stringFn(); // Uncaught TypeError: undefined is not a function
  */

  console.log('===============================');

  // 5. js定义一个类型Aclass,在这个类型中可以使用prototype为Aclass类添加属性和方法
  function myClass(){
     this.myClassAttr = '5.1 这是自定义的myClass类的内部属性myClassAttr';
     this.myMethod = function(){
        console.log('5.2 这是自定义的myClass类的内部方法myMethod');
      }
   }
  myClass.prototype.myClassAttr = '5.3 myClass类外部prototype的同名属性myClassAttr';
  myClass.prototype.myMethod = function () {
     console.log('5.4 myClass类外部prototype的同名方法myMethod');
  };
  var myObj = new myClass(); // 调用的属性和方法仍是Aclass内部最初定义的结果
  console.log(myObj.myClassAttr); // 5.1 ...
  myObj.myMethod(); // 5.2 ...

  console.log('===============================');

  // 6. 可以在外部使用prototype为自定义的类型添加属性和方法
  function aClass(){ // 自定义的aClass类
    this.aClassAttrInner = '6.1 这是自定义的aClass类的内部属性 aClassAttrInner';
    this.aClassFnInner = function(){
       console.log('6.2 这是自定义的aClass类的内部方法 aClassFnInner')
    };
  };
  aClass.prototype.aClassAttrOuter = '6.3 自定义的aClass类prototype的外部属性 aClassAttrOuter';
  aClass.prototype.aClassFnOuter = function(){
    console.log('6.4 自定义的aClass类prototype外部方法 aClassFnOuter');
  };
  var ac1 = new aClass();
  console.log(ac1.aClassAttrInner); // 调用aClass类的内部属性,输出: 6.1 ...
  ac1.aClassFnInner(); // 调用aClass类的内部方法,输出: 6.2 ...
  console.log(ac1.aClassAttrOuter); // 外部prototype的属性aClassAttrOuter,输出: 6.3 ...
  ac1.aClassFnOuter(); // 外部prototype的方法aClassFnOuter,输出: 6.4 ...

  console.log('===============================');

  // 7. 外部不能通过prototype改变自定义类型bClass的属性或方法
  function bClass(){
    this.bClassAttr = '7.1 自定义类型bClass的同名内部属性 bClassAttr';
    this.bClassFn = function(){
      console.log('7.2 自定义类型bClass的同名内部方法 bClassFn');
    };
  };
  bClass.prototype.bClassAttr = '7.3 自定义类型bClass的同名外部prototype属性 bClassAttr';
  bClass.prototype.bClassFn = function(){
     console.log('7.4 自定义类型bClass的同名外部prototype方法 bClassFn');
  };
  var bc1 = new bClass();
  console.log(bc1.bClassAttr); // 调用内部同名属性bClassAttr,输出: 7.1 ...
  bc1.bClassFn(); // 调用内部同名方法bClassFn,输出: 7.2 ...

  console.log('===============================');

  // 8. 可以在对象上改变属性或方法,相当于重写了原来的类的属性或方法
  function dClass(){
   this.dClassAttr = '8.1 dClass类内部的同名属性 dClassAttr';
   this.dClassFn = function(){
      console.log('8.2 dClass类的内部同名方法 dClassFn');
   };
  };
  var dc1 = new dClass();
  dc1.dClassAttr = '8.3 在实例中重写了同名属性 dClassAttr';
  console.log(dc1.dClassAttr); // 重写之后的值,输出: 8.3 ...
  dc1.dClassFn = function(){
    console.log('8.4 在实例中重写了同名方法 dClassFn');
  };
  dc1.dClassFn(); // 重写之后的值,输出: 8.4 ...

  console.log('===============================');

  // 9. 一个类型如何从另一个类型继承
  function Person(){ // 自定义父类
    this.commonPersonAttr = '9.1 父类Person的公共属性 commonPersonAttr - 都是猴子';
    this.commonPersonFn = function(){
      console.log('9.2 父类Person的公共方法 commonPersonFn - 都会吃');
    };
  };
  function ManPer(){ // 自定义子类
    this.manAttr  = '9.3 子类ManPer的属性 manAttr - 男猴子有喉结';
    this.manFn = function(){
       console.log('9.4 子类ManPer的方法 manFn - 男猴子体力强');
    };
  };
  // 将父类Person这个对象,赋值给子类ManPer的prototype,子类继承了父类的全部属性
  ManPer.prototype = new Person(); // *重点*
  var manP1 = new ManPer(); // 实例manP1拥有了父类和子类的全部属性
  console.log(manP1.commonPersonAttr); // 父类的属性commonPersonAttr,输出: 9.1 ...
  manP1.commonPersonFn(); // 父类方法commonPersonFn,输出: 9.2 ...
  console.log(manP1.manAttr); // 子类属性manAttr,输出: 9.3 ...
  manP1.manFn(); // 子类方法manFn, 输出: 9.4 ...

  ManPer.prototype.commonPersonAttr = '9.5 子类ManPer重写父类Person的属性 commonPersonAttr - 男猴子都命短';
  ManPer.prototype.commonPersonFn = function(){
    console.log('9.6 子类ManPer重写父类Person的方法 commonPersonFn - 男猴子都吃的多');
  };
  var manP2 = new ManPer();
  console.log(manP2.commonPersonAttr); // 重写之后属性,输出: 9.5 ...
  manP2.commonPersonFn(); // 重写之后方法,输出: 9.6 ...
</script>
⚠️ **GitHub.com Fallback** ⚠️