【JavaScript】面向对象
JS(JavaScript)
一.面向对象;
概述;
- 面向对象是什么;
是使用一系列对象相互协作软件设计,目的是在编程中促进更好灵活性和可维护性,凭借对模块化重视,面向对象代码开发更简单,容易理解
面向对象的有主要特征是1.封装;2.继承;3.多态
- 封装;
封装主要用于叙述对象中所包含(封装)的内容,由两部分组成
相关的数据(储存属性)
这些数据所能做的事情
- 继承;
是指类和类之间的关系,如两个类都有相同的属性和方法,那么其中一个类并可以继承另一个类,这样不需要再次定义同样的属性和方法
创建一个或多个类专门类方式称为继承,有两个类其中一个叫子类,另一个是叫做父类
- 多态;
不同的对象可以定义有相同名称方法,方法是作用所在对象中,不同对象相同方法调用各自行为能力则为多态
如A对象有sayMe()方法,B对象继承A对象,而B对象也有具有sayMe()方法,sayMe()方法时,并不知道该方法A对象还是B对象,且不影响代码正常工作
2.构造函数;
- 构造函数;
构造函数称为构造器和对象模版是对象的一饿方法,构造器被调用,在
JS(JavaScript)中函数可以作为构造器使用,,并不需要定义个构造器方法
- 构造函数的属性;
就是对象的变量,一个对象包含多个属性,定义构造函数属性是使用this关键字
- 构造函数的方法;
该方法,很想构造函数属性,不同是方法是个函数(或像函数一样定义)定义构造函数属性是使用this关键字
- this关键字
有套完全不同于其它语言对this处理机制,this关键字本身没有任何意义
/* 用于创建对象(属性和方法) 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('我是犬夜叉'); } }
二.Object类型;
1.操作对象的属性;
- 设置属性描述符value;
是该属性所对应值,可以是如何有效的JS(JavaScript)值(数值,对象,函数)为默认值undefined
var obj = { // 定义对象的同时定义了该属性以及值(可修改、可删除以及可枚举的) name : '犬夜叉' } Object.defineProperty(obj, 'name', { value : '桔梗' }); console.log(obj.name);// 桔梗 /* 同样都是为对象新增属性 1.如果直接使用 "对象名.属性名 = 值" -> 可修改、可删除以及可枚举的 2.如果使用Object.defineProperty()方法新增属性 * 该新属性是不可修改、不可删除以及不可枚举的 */ Object.defineProperty(obj, 'age', { value : 16 }); console.log(obj.age);// 16 var result1 = Object.getOwnPropertyDescriptor(obj, 'age'); console.log(result1); // 一旦属性的值是不可修改的 - 如果执行修改操作时 -> 没有语法报错,但是无效 obj.age = 80; console.log(obj.age);// 16 obj.job = '妖狐'; var result2 = Object.getOwnPropertyDescriptor(obj, 'job'); console.log(result2);
- 设置属性描述符writable;
当该属性为true时,value才能被赋值运算符所改变,默认为false
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 : 18, writable : true }); console.log(obj.age);// 16 // 修改age属性值 obj.age = 80; console.log(obj.age);// 80 // 删除age属性值 delete obj.age; console.log(obj.age);// undefined
- 设置属性描述符configurable;
该属性为true时,该属性描述符才能改变,同时会从相同的对象中被删除,默认为false
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;
该属性为true时,属性才能出现在对象枚举属性中,默认为false
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 = { sayMe : function(){ console.log('this is function'); } } var result = Object.getOwnPropertyDescriptor(obj, 'sayMe'); console.log(result); Object.defineProperty(obj, 'sayMe', { value : function(){ console.log('this is new function'); }, writable : false }); obj.sayMe(); obj.sayMe = function(){ console.log('这是犬夜叉'); } obj.sayMe();
- 属性描述符存取器
var obj = { name : '犬夜叉' } var value;// 全局变量 Object.defineProperty(obj,'name',{// 当获取或访问当前属性时,会调用get方法 get : function () { // 获取指定的属性值 console.log('Inuyasha'); /* get方法在被调用时,不能传递任何参数 get方法在被调用时,允许传递this关键字 this - 表示当前的目标对象(不能调用对象的当前目标属性) */ return value;// 由于变量为初始化,调用时可能结果为 undefined }, set : function (newValue) { console.log('Inuyasha: ' + value); value = newValue; /* set方法在被调用时,允许传递this关键字 this - 表示当前的目标对象(不能调用对象的当前目标属性) */ } }) console.log(obj.name);// undefined obj.name = '桔梗'; console.log(obj.name);//桔梗
2.防篡改对象;
- 禁止扩展
Object.preventExtensions()表示对象不可扩展,不能新增属性和方法
Object.isExtensible()表示判断是否可扩展
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);
- 密封对象
Object.seal()表示封闭个对象,阻止增加新属性,现有属性不可设置,
Object.isSealed()判断个对象是否密封
var obj = { name : '犬夜叉' // 表示可修改 }; console.log(Object.getOwnPropertyDescriptor(obj, 'name')); /* 将该对象进行密封 1.不能为该对象新增属性或方法 2.不能修改该对象的属性或方法的描述符 * configurable * enumerable */ Object.seal(obj); console.log(Object.getOwnPropertyDescriptor(obj, 'name')); /*Object.defineProperty(obj, 'age', { value : 16 });*/ Object.defineProperty(obj, 'name', { value : '桔梗', writable : false, // 表示不可修改 configurable : true, enumerable : false }); console.log(Object.getOwnPropertyDescriptor(obj, 'name')) console.log(obj); obj.name = '戈薇'; console.log(obj);
- 冻结对象
Object.freeze()冻结个对象,不能增加新属性给该对象,也不能修改此属性值,已有属性不能删除,也不能修改此对象的属性,该方法返回被冻结对象
Object.isFrozen()判断个对象是否被冻结
var obj = { name : '犬夜叉' } // 冻结对象 Object.freeze(obj); /*obj.age = 16; console.log(obj); obj.name = '桔梗'; console.log(obj); delete obj.name; console.log(obj);*/ Object.defineProperty(obj, 'age', { value : 16 }); console.log(obj);