20200917 王维

学习总结

面向对象

多态

同一个方法,在不同情况下表现出不同的状态

重载与重写

重载 使用函数中的arguments判断传入参数的不同,导向不同的分支,实现不同的功能

重写 如果子对象觉得父对象的成员不好用,可在子对象中定义一个和父对象中同名的成员,以此来覆盖父对象中同名成员

静态方法

不需要创建子对象,就可用构造函数直接调用的方法,其实就是将全局函数,找到地方保存而已

提示:其实就是把全局函数,强行添加给某个构造函数对象。具体添加到哪个构造函数,要看这个函数做的事儿和谁家的名称更接近

常见的静态方法

Array.isArray(obj)
判断任意一个对象是否为数组
Object.defineProperties(obj,props)
直接在一个对象上定义一个或多个新的属性或修改现有的属性,并返回该对象
var obj=new Object();
Object.defineProperties(obj,{
name:{
value:"张三",
configurable:false,
wirtable:true,
enumerable:true
},
age:{
value:20,
configurable:true
}
})
console.log(obj.name,obj.age)
obj
将要被添加的属性或修改的属性
props
该对象的一个或多个键值对,定义了将要为对象添加或修改的属性
Object.setPrototypeOf(obj,prototype)
将一个指定的对象的原型设置为另一个对象或者null(既对象的[[Prototype]]内部属性)
function fn1(name,sex){
this.name=name;
this.sex=sex;
}
function fn2(name,age){
this.name=name;
this.age=age;
}
fn2.prototype.say=function(){
console.log(sex:${this.sex})
}
var fn11=new fn1("lili",11)
var fn22=new fn2("mingming",22)
Object.setPrototypeOf(fn11,fn22)
fn11.say()
obj
将被设置原型的对象
prototype
该对象新的原型(可以是一个对象或者null)

自定义继承

如果觉得一个对象的整个父对象都不好用,就可以更换这个子对象的父对象

程序中,只要觉得当前的原型对象里没有自己想要的成员,想用别的类型的原型对象里的成员,就可以更换当前对象的__proto__指向新的父对象

仅基于现有父对象,创建子对象,并扩展自有属性: Object.create()
创建新子对象,继承父对象,扩展子对象自有属性
var child=Object.create(father,{
属性名:{
// 四大特性
value:"属性值",
writable:false,
enumerable:true,
configurable:true
},
...
})
value:实际为属性保存的属性值
writable:true/false
控制是否可修改当前属性
enumerable:true/false
控制是否可用for in遍历这个属性
configurable:ture/false
控制两件事
是否可删除该属性
是否可修改前两个特性
实例
var parent={
name:"lili",
age:20
}
var child=Object.create(parent,{
sex:{
value:"女",
writable:false,
enumerable:true,
configurable:false
}
})
console.log(child.__proto__)
console.log(child.name)
常用方法:模拟实现Object.create()
Object.create = function(father, props) {
// var child=new Object();
// Object.setPrototypeOf(child,father);
var Fun = function() {}
Fun.prototype = father
var child = new Fun()
// Object.defineProperties(child,props);
if (props !== undefined) {
for (var key in props) {
child[key] = props[key].value
}
}
return child
}
var parent={
name:"lili"
}
var child=Object.create(parent,{
sex:{
value:"男",
writable:false,
enumerable:true,
configurable:false
}
})
console.log(child)

ES5

严格模式

整个代码块或js文件启用严格模式 在代码块或js文件的开头插入: "use strict";

仅在一个函数内启用严格模式 在function内,函数体顶部插入: "use strict";

严格模式规定

禁止给未声明的变量赋值
普通JavaScript中,给一个未声明的变量强行赋值,会自动在全局创建该变量。结果会造成内存泄漏。严格模式下,只要给一个未声明的变量赋值,就会报错。好处是避免内存泄漏
静默失败升级为错误
什么是静默失败?
执行不成功,还不报错,缺点是不知道原因,无法调试
严格模式下,所有静默失败都升级为错误,便于调试,减少了歧义
普通函数调用或匿名函数自调中的this不再默认指向window,而是undefined
后果:如果误给this赋值,会报错。因为undefined后,什么也不能加。只要加,就报错。好事儿,避免了无意中生成全局变量,造成内存泄漏和全局污染
禁止使用 arguments.callee
提示:arguments.callee,专门在函数执行时,在函数内部自动引用当前函数自己的特殊变量
什么时候使用 arguments.callee?
递归调用
递归的问题1:如果在函数内写死函数名,则万一函数名变化,忘记修改内部,立刻程序就出错,紧耦合
解决
arguments.callee 代替写死的函数名,松耦合, 修改函数名,函数内可不用修改
递归的问题2:递归的效率极低,重复计算量太大。所以严格模式禁用了arguments.callee,等效于暗示你不要使用递归算法
解决
几乎所有的递归都可以用循环代替。难度,用海量数据找规律
实例:斐波那契数列
function fib(n){
if(n<3){
return 1;
}else{
return arguments.callee(n-1)+arguments.callee(n-2)
}
}
console.log(fib(10));
实例:使用循环代替菲波那切数列
function fib(n){
if(n<3){
return 1;
}else{
var f1=1, f2=1, fn;
// 反复执行相同的操作(不是从第一个开始循环,而是从第三开始计算)
for(var i=3;i<=n;i++){
// 每次先将f1的值和f2的值相加,放入fn中
fn=f1+f2;
// 为下一轮循环做准备:
//将f2的值给f1,再将fn的值给f2
f1=f2;
f2=fn;
}
// 循环结束,fn变量中的值,就是对应值
return fn;
}
}
console.log(fib(10));

JSON对象

JSON.parse(string/json)
反序列化操作,解析JSON字符串得到JavaScript对象
var json='{"x":60,"y":30}';
var jsObj=JSON.parse(json);
JSON.stringify(object)
序列化操作,将JavaScript对象转换为JSON字符串
var obj={
name:"lili",
age:20
}
var jsonObj=JSON.stringify(obj)

对象保护

保护单个对象的属性

命名属性:数据属性 访问器属性

内部属性:

包括
__proto__
提示:指向当前对象的原型对象,即父对象
Object.getPrototypeOf(obj)
用于获取指定对象的原型对象,即__proto__的指向,与obj.__proto__的结果一致
class
Object.prototype.toString.call(obj)
提示:主要用来检测数据类型,可以十分精确的判断
注意:prototype是函数所独有的,函数也是对象,prototype指向当前函数的原型对象,找到该函数的属性和方法
结果:[object Object]
extensible
提示:用于控制对象是否可扩展
Object.isExtensible(obj)
用于判断一个对象是否是可扩展的
extensible:true

防篡改

​ 防扩展 禁止添加新属性,相当于将对象的extensible:false

Object.preventExtensions(obj)

Object.isExtensible(obj)

​ 密封 在兼具防扩展同时,又进一步禁止删除属性。但是,属性值还是可以修改的。在防扩展同时,禁止删除现有属性,相当于将每个属性的configurable:false,其他属性在修改特性时,不必反复修改configurable:false

Object.seal(obj)

Object.isSealed(obj)

​ 冻结 即不能添加新属性,又不能删除现有属性。甚至连属性值都不能修改。在密封同时,禁止修改所有属性的值,相当于将每个属性的writable:false

Object.isSealed(obj)

Object.isFrozen(obj);

Object.create()

Object.create()共做了3件事

  1. 先创建一个新的子对象
  2. 让新的子对象继承父对象
  3. 为新的子对象添加自有属性

var father = {
bal: 1000000,
car: '宝马'
}
var child = Object.create(father, {
phone: {
value: 'iPhoneX',
writable: true,
enumerable: true
},
bao: {
value: 'LV',
writable: true,
enumerable: true
}
})
Object.seal(child)
console.log(child)
console.log(child.bal, child.car)
console.log(child.phone, child.bao)

心得体会

对象中的属性分为内部属性和命名属性,其中命名属性有分为数据属性和访问器属性,对访问器属性的用法和定义了解不是很透彻

学习了多种对象创建和属性添加的方法 对各个方法之间的差异和优缺点了解不是很透彻

标签

评论

this is is footer