JavaScript面向对象特性

面向对象与面向过程的区别:

面向过程

面向过程

面向对象

面向对象

*** √Tips:面向过程思想注重具体的步骤;面向对象思想注重的是一个个对象。面向对象思想可以使代码结构清晰、层次分明,所以它可以帮助团队更好的分工协助,提高开发效率。


面向对象的特征:主要包括封装性、继承性和多态性

1、封装性(表单生成器)

封装指的是隐藏内部的实现细节,只对外开放操作接口



(function(window) {

var FormBuilder =function(data) {

this.data = data;

};

window.FormBuilder =FormBuilder;

})(window);

上述代码将表单生成器封装成一个构造函数。其中最外层是一个自调用的匿名函数,在调用时传入的window对象用于控制FormBuilder库的作用范围,再通过window.FormBuilder =FormBuilder;将FormBuilder作为传入对象的属性;

在匿名函数中定义的变量、函数都不会污染全局作用域,体现了面向对象的封装性。

2、继承性

继承是指一个对象继承另一个对象的成员,从而在不改变另一个对象的前提下进行扩展


(1)、利用原型对象实现继承

如果一个对象中本来没有某个属性或方法,但可以从另一个对象中获得即继承


function Person(name) {

this.name = nam`e;

}

Person.prototype.sayHello =function () {

console.log('你好,我是' +this.name);

}

var p1 =new Person('Jim');

var p2 =new Person('Tom');

p1.sayHello();// 输出结果:你好,我是Jim

p2.sayHello();// 输出结果:你好,我是 Tom

//p1、p2本无sayHello()成员,但在构造函数Person的原型对象添加了sayHello()成员后,p1、p2也拥有了sayHello()成员,即p1、p2对象继承了原型对象中的成员。

(2)替换原型对象实现继承

将构造函数的原型对象替换成另一个对象A,该构造函数创建的对象就会继承新的原型对象


function Person() {}// 构造函数Person原本有一个原型对象prototype

Person.prototype = {// 将构造函数的prototype属性指向一个新的对象

  sayHello:function () {// 在新的对象中定义一个sayHello()方法用于测试

    console.log('你好,我是新对象');

}

}

var p =new Person();

p.sayHello();// 输出结果:你好,我是新对象

在基于构造函数创建对象时,代码应写在替换原型对象之后


function Person() {}

Person.prototype.sayHello =function() {

console.log('原来的对象');

}

var p1 =new Person();

Person.prototype = {

sayHello:function(){

console.log('替换后的对象');

}

}

var p2 =new Person();

p1.sayHello();// 输出结果:原来的对象

p2.sayHello();// 输出结果:替换后的对象

//在通过替换原型对象的方式实现继承时要注意代码编写的顺序

(3)利用Object.create()实现继承


var obj = {

sayHello:function(){

console.log('我是一个带有sayHello方法的对象');

}

};

var newObj =Object.create(obj);

newObj.sayHello();// 输出结果:我是一个带有sayHello方法的对象

newObj.__proto__ ===obj;// 返回结果:true

//上述代码实现了将obj对象作为newObj对象原型,newObj对象继承了obj对象的sayHello()方法

(4)混入继承

将一个对象的成员加入到另一个对象中,实现对象功能的扩展


var o1 = {};

var o2 = {name:'Jim'};

o1.name =o2.name;// o1继承o2的name属性

console.log(o1.name);// 输出结果:Jim

当对象成员比较多时,可以编写一个函数专门实现对象成员的赋值,函数通常命名为mix(混合)或extend(扩展)


// 编写extend函数

function extend(o1, o2) {

for (var k in o2) {

o1[k] = o2[k];

}

}

// 测试extend函数

var o1 = {name:'Jim'};

var o2 = {age:16,gender:'male'};

extend(o1,o2);// 将o2的成员添加给o1

console.log(o1.name);// 输出结果:Jim

console.log(o1.age);// 输出结果:16

混入式继承和原型继承还可以组合在一起使用,实现以对象的方式传递参数,或以对象的方式扩展原型对象成员


function Person(options) {

// 调用前面编写的extend(),将传入的options对象的成员添加到实例对象中

  extend(this, options);

}

Person.fn =Person.prototype;// 将prototype属性简化为fn方便代码书写

Person.fn.extend =function(obj) {

extend(this, obj);// 此处的this相当于Peron.prototype

};

//以此之下五行代码演示了以对象的方式扩展原型对象的成员,当需要为原型对象一次添加多个成员时,使用这种方式会非常方便,只需将这些成员保存到一个对象中,再调用extend()方法来继承

Person.fn.extend({

sayHello:function() {

console.log('你好,我是' + (this.name ||'无名'));

}

});

var p1 =new Person();

var p2 =new Person({name:'张三',age:16});//通过Person()构造函数创建对象时传入了对象形式的参数,这种传递参数的方式相比传递多个参数更加灵活

p1.sayHello();// 输出结果:你好,我是无名

p2.sayHello();// 输出结果:你好,我是张三

3、多态性

多态指的是同一个操作作用于不同的对象,会产生不同的执行结果。JavaScript中一个变量可以存储任意类型的数据就是多态性的体现。其中如数字、数组、函数都具有toString()方法,当使用不同的对象调用该方法时,执行不同的结果。



var obj =123;

console.log(obj.toString());// 输出结果:123

obj = [1,2,3];

console.log(obj.toString());// 输出结果:1,2,3

obj =function() {};

console.log(obj.toString());// 输出结果:function () {}

//面向对象中,多态性的实现基本离不开继承。因为当多个对象继承了同一个对象后,就获得了相同的方法,然而根据每个对象的需求来改变同名方法的执行结果。

ps:例子程序

包含了一些面向对象属性的特性

var elements = [
        {tag: 'input', text: '姓名:', attr: {type: 'text', name: 'user'}},//将姓名:<input type="text" name="user">转化为对象
        {tag: 'input', text: '性别:', attr: {type: 'radio', name: 'gender'}, option: {m: '男', w: '女'}},
        {tag: 'input', text: '爱好:', attr: {type: 'checkbox', name: 'hobby[]'}, option: {swimming: '游泳', reading: '读书', running: '跑步'}},
        {tag: 'select', text:'住址:', attr: {name: 'area'}, option: {'': '--请选择--', bj: '北京', sh: '上海', sz: '深圳'}},
        {tag: 'textarea', text: '自我介绍:', attr: {name: 'introduce', cols:'50', rows: '5'}},
        {tag: 'input', attr: {type: 'submit', value: '确定'}}
      ];
//上述代码中,每个表单项都具有tag、text、attr和option4个属性,表示它们具有相同的特征。而每个表单项的标签名、提示文本、属性值是不同的,这表示每个对象都有不同之处
      document.getElementById('form').innerHTML = new FormBuilder(elements).create();
//封装表单生成器,前面有详解
(function(window) {
  var FormBuilder = function(data) {
    this.data = data;
  };

//接下来的所有代码都是为了实现表单的自动生成
//编写create()方法
  FormBuilder.prototype.create = function() {
    var html = '';
    for (var k in this.data) {//this.data表示传入的elements数组
      var item = {tag: '', text: '', attr: {}, option: null};
      for (var n in this.data[k]) {//接下来7行代码遍历整个数组
        item[n] = this.data[k][n];
      }
      html += builder.toHTML(item);
    }
    return '<table>' + html + '</table>';
  };//上述11行代码实现了表单的自动的生成
//编写builder对象,builder是封装在匿名函数内部的对象,专门用于对每一种表单项进行生成
  var builder = {
    toHTML: function(obj) {
      var html = this.item[obj.tag](this.attr(obj.attr), obj.option);
      return '<tr><th>' + obj.text + '</th><td>' + html + '</td></tr>';
    },//上述3行代码中,“this.item[obj.tag]()”用于根据obj.tag的值来调用item对象中的方法。当obj.tag的值为input时,就表示调用builder.item.input()方法

//接下来编写attr()方法,实现将“{type:'text',name:'user'}”形式的对象转换为“type="text" name="user"”形式的HTML字符串
    attr: function(attr) {
      var html = '';
      for(var k in attr) {
        html += k + '="' + attr[k] + '" ';
      }
      return html;
    },
//编写item对象
    item: {
      input: function(attr, option) {
        var html = '';
        if (option === null) {//通过判断option是否为null,来区分单个控件和组合控件
           html += '<input ' + attr + '>';
        } else {
          for (var k in option) {
            html += '<label><input ' + attr + 'value="'  + k + '"' + '>' + option[k] + '</label>';//在生成组合控件时使用label标签包裹input标签,这样可以扩大选择范围,当单击提示文本时,相应的表单控件就会被选中
          }
        }
        return html;
      },
      select: function(attr, option) {
        var html = '';
        for (var k in option) {
          html += '<option value="' + k + '">' + option[k] + '</option>';
        }
        return '<select ' + attr +'>' + html + '</select>';
      },
//编写item对象中的textarea()方法
      textarea: function(attr) {
        return '<textarea ' + attr + '></textarea>';
      }
    }
  };
  window.FormBuilder = FormBuilder;
})(window);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  •   面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意...
    霜天晓阅读 6,497评论 0 6
  • 一、 JS面向对象编程 1、 面向对象介绍 什么是对象? Everything is object (万物皆对象)...
    宠辱不惊丶岁月静好阅读 4,318评论 0 2
  • 博客内容:什么是面向对象为什么要面向对象面向对象编程的特性和原则理解对象属性创建对象继承 什么是面向对象 面向对象...
    _Dot912阅读 5,327评论 3 12
  • 基本概念 语法区分大小写标识符注释严格模式语句 关键字和保留字 变量 数据类型typeof 操作符Undefine...
    他爱在黑暗中漫游阅读 5,127评论 0 1
  • 对一个女人来说 一顿美食 是30分钟的满足 一件衣服 是3天的喜欢 一个包包 是3周的快乐 一张比同龄人娇嫩的容颜...
    王恩磊阅读 2,481评论 0 0

友情链接更多精彩内容