摘要:面向对象面向对象是什么面向对象编程简称相似的对象称为类面向对象编程的三个主要特征是封装继承多态所有的程序是由一定的属性和行为对象组成的不同的对象的访问通过函数调用来完成对象间所有的交流都是通过方法调用通过对封装对象数据提高复用率是一种基于原
面向对象 面向对象是什么
面向对象编程 简称OOP 相似的对象 称为类
面向对象编程的三个主要特征是:1.封装 2.继承 3.多态
所有的程序是由一定的属性和行为对象组成的 不同的对象的访问通过函数调用来完成 对象间所有的交流都是通过方法调用 通过对封装对象数据 提高复用率
JavaScript是一种基于原型的面向对象编程 而不是基于类的
封装
封装是按照要求使用并得到对应的结果 而不需要知道其真实的执行原理是怎样的 关心入出 不看结果
封装主要用于阐述对象中所包含(或封装)的内容 由两部分组成:
1.相关的数据
2.基于这些数据所能做的事情
继承
继承是指类与类之间的关系 如果两个类都有相同的属性或方法 那么可以让一个类继承于另一个类 这样就不需要在前者再次定义同样的属性或方法
创建一个或多个类的专门版本类方式称为继承(JavaScript只支持单继承)创建的专门版本的类通常叫做子类 另外的类通常叫做父类
多态
不同的对象可以定义具有相同名称的方法 方法的作用于所在的对象中 这种不同对象通过相同方法的调用实现各自行为的能力 被称为多态
构造函数构造函数又称为构造器或对象模板 是对象中的一个方法 在实例化时构造器被调用 在JavaScript中函数就可以作为构造器使用 因此不需要特定地定义一个构造器方法
/* 创建构造函数(类的概念) - 用于常见对象(属性和方法) function 构造函数名称(){ this.属性名 = 属性值; this.方法名 = function(){ 方法体 } } * this关键字 - 指代利用当前构造函数创建的对象 */ function Hero(name){ this.name = name; this.sayMe = function(){ console.log("我是"+ name); } } //利用构造函数创建对象 var hero = new Hero("张三"); console.log(hero); var obj = { name:"张三", sayMe:function(){ console.log("我是张三"); } }构造函数的属性
构造函数的属性实际上就是对象的变量 一个对象可以包含多个属性 定义构造函数的属性时使用this关键字
//1.函数;2.构造函数 function Hero(name){ var v = 100;//局部变量 function n(){};//内部函数 this.name = name;//属性 this.sayMe = function(){//属性 console.log("我是"+ name); } } //1.函数调用 Hero(); //2.构造函数使用 var hero = new Hero(); function fun(){ var v = 100;//局部变量 //方法 this.get = function(){ return v; } this.set = function(value){ v = value; } } //构造函数 var f = new fun(); console.log(f); console.log(f.get()); f.set(200); console.log(f.get())Object类型
Object创建对象
//表示创建一个空对象 var obj1 = new Object(null); var obj2 = new Object(undefined); //表示创建一个与给定值对应类型的对象 var obj3 = new Object(100); console.log(obj3);//[Number:100] var num = new Number(100); console.log(num);//[Number:100] //当以非构造函数形式被调用时 Object等同于new Object() var obj4 = Object();//函数调用 var obj5 = new Object();//构造函数调用
获取属性描述符
JavaScript提供了一个内部数据结构 用于描述对象的值 控制其行为 例如该属性是否可写 是否可配置 是否可修改以及是否可枚举等 这个内部数据结构被称为"属性描述符"
每个属性都有自己对应的属性描述符 保存该元素的元信息
/* 通过定义对象(属性或方法)这种方式 * 属性默认都是数据描述符 */ var obj = { name : "李四" } /* 使用Object.getOwnPropertyDescriptor()方法获取指定属性的描述符 Object.getOwnPropertyDescriptor(obj,prop) * obj - 表示指定属性对应的目标对象 * prop - 表示获取描述符的目标属性名称 * 返回值 - 其属性描述符对象 */ var result = Object.getOwnPropertyDescriptor(obj,"name"); console.log(result);
对象目前存在的属性描述符有两种主要形式:数据描述和存取描述符
数据描述符数据描述符是一个具有值的属性 该属性可能是可写的 也可能是不可写的 数据描述符具有以下可选键值:
1.value:该属性对应的值 可以是任何有效的JaveScript值(数值 对象 函数等)默认为undefined
2.writable:当且仅该属性的writable为true时 value才能被赋值运算符改变 默认为false
3.configurable:当且该属性的configurable 为true时 该属性描述符才能够被改变 同时该属性也能从对应的对象上被删除 默认为false
4.enumerable:当且仅该属性的enumerable为true时 该属性才能够出现在对象的枚举属性中 默认为false
设置属性描述符value
var obj = { // 定义对象的同时定义了该属性以及值(可修改、可删除以及可枚举的) name : "张三" } /* Object.defineProperty(obj, prop, desc)方法 * 作用 * 用于定义目标对象的新属性 * 用于修改目标对象的已存在属性 * 参数 * obj - 表示目标对象 * prop - 表示目标对象的目标属性名称 * desc - 表示属性描述符,必须是对象格式 { value : 值 } * 返回值 - 返回传递的对象 */ Object.defineProperty(obj, "name", { value : "李四" }); console.log(obj.name);// 李四 /* 同样都是为对象新增属性 1.如果直接使用 "对象名.属性名 = 值" -> 可修改、可删除以及可枚举的 2.如果使用Object.defineProperty()方法新增属性 * 该新属性是不可修改、不可删除以及不可枚举的 */ Object.defineProperty(obj, "age", { value : 28 }); console.log(obj.age);// 18 var result1 = Object.getOwnPropertyDescriptor(obj, "age"); console.log(result1); // 一旦属性的值是不可修改的 - 如果执行修改操作时 -> 没有语法报错,但是无效 obj.age = 80; console.log(obj.age);// 18 obj.job = "游侠"; var result2 = Object.getOwnPropertyDescriptor(obj, "job"); console.log(result2);
设置属性描述符writable
var obj = { // 定义对象的同时定义了该属性以及值(可修改、可删除以及可枚举的) name : "张三" } // 修改现有属性 Object.defineProperty(obj, "name", { value : "李四", writable : false // 不可修改 }); console.log(obj.name);// 李四 // 修改name属性值 obj.name = "王五"; console.log(obj.name);// 李四 Object.defineProperty(obj, "age", { value : 28, writable : true }); console.log(obj.age);// 18 // 修改age属性值 obj.age = 80; console.log(obj.age);// 80 // 删除age属性值 delete obj.age; console.log(obj.age);// undefined
设置属性描述符configurable
var obj = { //定义对象的同时定义了该属性以及值(可修改 可删除以及可枚举的) name : "张三" } //修改现在属性 Object.defineProperty(obj,"name",{ value : "李四", writable : true,//控制当前属性是否可以被修改 configurable : true //控制当前属性是否可被修改 }); console.log(obj.name);//李四 //修改name属性值 obj.name = "王五"; console.log(obj.name);//李四 //删除name属性值 delete obj.name; console.log(obj.name);//李四
设置属性描述符enumerable
var obj = { // 定义对象的同时定义了该属性以及值(可修改、可删除以及可枚举的) name : "张三" } Object.defineProperty(obj, "name", { value : "李四", enumerable : false }); console.log(obj.name);// 李四 /* 属性描述符enumerable - 控制当前属性是否可被枚举(遍历) * 仅能循环遍历对象中可被枚举的属性 * for...in语句 * keys()方法 * 可以循环遍历对象中可被枚举和不可被枚举的属性 * getOwnPropertyNames()方法 */ for (var i in obj) { console.log(i); } var result1 = Object.keys(obj); console.log(result1); var result2 = Object.getOwnPropertyNames(obj); console.log(result2);
属性描述符存取器
var obj = { name : "张三" } var value;// 全局变量 Object.defineProperty(obj, "name", { // 获取指定的属性值 get : function(){// 当获取或访问当前属性时,会调用get方法 console.log("this is get function"); /* 类似于数据描述符中的value * get方法在被调用时,不能传递任何参数 * get方法在被调用时,允许传递this关键字 * this - 表示当前的目标对象(不能调用对象的当前目标属性) */ return value;// 由于变量为初始化,调用时可能结果为 undefined }, /* set方法用于定义当前目标属性的修改作用 * 该方法接收唯一的一个参数 -> 作为当前目标属性的新的值 * 通过属性修改操作指定的新的值 -> 作为形参对应的实参 */ set : function(newValue){ console.log("this is set function: " + value); /* set方法在被调用时,允许传递this关键字 * this - 表示当前的目标对象(不能调用对象的当前目标属性) */ value = newValue; } }); console.log(obj.name);// undefined obj.name = "王五"; console.log(obj.name);// 王五;// undefined放篡改对象
防篡改是什么
定义的对面默认在任何时候 任何位置 无论有意义的还是无意义的都可以修改对象的属性或方法
而这些篡改可能会影响对象的内置属性或方法 从而导致对象的正常功能可能无法使用
JaveScript在ECWASScript5版本中新增了放置篡改对象的属性或方法的机制 共提供了三级保护方式:
1.禁止扩展:禁止为对象扩展新的属性或方法
2.密封对象:禁止扩展新的属性或方法 禁止配置现有的属性或方法的描述符 仅允许读写属性的值
3.冻结对象:禁止对对象执行任何修改操作
禁止扩展
var obj = {}; // 将对象设置禁止扩展 Object.preventExtensions(obj); // 新增属性或方法无效 -> 语法没有报错 obj.name = "张三"; console.log(obj); /* Object.defineProperty()方法新增属性 * 结果 - 报错 * 信息 - TypeError: Cannot define property:name, object is not extensible. */ Object.defineProperty(obj, "name", { value : "李四" }); console.log(obj); /* Object.isExtensible(obj)方法 * 作用 - 用于判断指定目标对象是否可扩展 * 返回值 * true - 表示指定目标对象是可扩展的 * false - 表示指定目标哦对象是不可扩展的 */ var result = Object.isExtensible(obj); console.log(result);
密封对象
密封对象 就是指禁止为对象扩展新的属性或方式 并且修改现有属性的描述符
//最简单的方法来生成一个密封对象 使用Objet.seal. var sealed = {}; Objet.seal(sealed); Objet.isSealed(sealed);//===true //一个密封对象同时也是不可扩展的 Objet.isExtensible(sealed);//===false
冻结对象
冻结对象 就是值禁止对象执行任何修改操作
var obj = { name : "张三" } // 冻结对象 Object.freeze(obj); /*obj.age = 18; console.log(obj); obj.name = "李四"; console.log(obj); delete obj.name; console.log(obj);*/ Object.defineProperty(obj, "age", { value : 18 }); console.log(obj);
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/108176.html
摘要:在中,并没有对抽象类和接口的支持。例如,当对象需要对象的能力时,可以有选择地把对象的构造器的原型指向对象,从而达到继承的效果。本节内容为设计模式与开发实践第一章笔记。 动态类型语言 编程语言按数据类型大体可以分为两类:静态类型语言与动态类型语言。 静态类型语言在编译时已确定变量类型,动态类型语言的变量类型要到程序运行时,待变量被赋值后,才具有某种类型。 而JavaScript是一门典型...
摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...
摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...
摘要:很多情况下,通常一个人类,即创建了一个具体的对象。对象就是数据,对象本身不包含方法。类是相似对象的描述,称为类的定义,是该类对象的蓝图或原型。在中,对象通过对类的实体化形成的对象。一类的对象抽取出来。注意中,对象一定是通过类的实例化来的。 showImg(https://segmentfault.com/img/bVTJ3H?w=900&h=385); 马上就要到七夕了,离年底老妈老爸...
摘要:有一函数若是用来生成对象,则称为构造函数名。属性指定了使用该构造函数生成的对象实例继承了哪个对象实例。因此,只要利用,就能在构造函数中,为未来利用此构造函数生成的对象实例,添加成员属性和成员方法了。 与其它编程语言不一样的是,javascript的面向对象并非依赖于抽象的类,而是通过原型链,将一个个具体的对象实例进行连接,位于原型链下游的对象实例可以读取/使用位于上游的对象实例的属性/...
摘要:虽然,也是面向疾苦的语言,但是,它和静态类型语言的面向接口编程不一而足。对象对他自己的行为负责,其他对象不关心它的内部实现。 ‘工欲善其事,必先利其器’,在深入学习JavaScript之前,我认为我们很有必要了解以下,JavaScript这门面向对象的动态语言到底是一门什么样的语言。 JavaScript vs 其他面向对象语言 它没有使用像Java等传统的面向对象语言的类式继承,而...
阅读 2437·2021-10-09 09:44
阅读 3796·2021-09-22 15:43
阅读 2926·2021-09-02 09:47
阅读 2544·2021-08-12 13:29
阅读 3872·2019-08-30 15:43
阅读 1682·2019-08-30 13:06
阅读 2191·2019-08-29 16:07
阅读 2748·2019-08-29 15:23