diff --git "a/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\344\270\245\346\240\274\345\207\275\346\225\260.md" "b/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\344\270\245\346\240\274\345\207\275\346\225\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..cf3c06893619a9a617788b75e8f357256e6a1ebd --- /dev/null +++ "b/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\344\270\245\346\240\274\345\207\275\346\225\260.md" @@ -0,0 +1,40 @@ +``` + // //1. + // function fn(a){ + // this.a = a + // } + // var obj={}; + // var getNum = fn.bind(obj); + // getNum(2); + // console.log(obj.a);//2 + + // //2. + // function fun(n,o) { + // console.log(o); + // return{ + // fun:function (m) { + // return fun(m,n) + // } + // } + // } + + // var a= fun(0);a.fun(1);a.fun(2);a.fun(3);// undefined ; 0 ; 0 ;0; + // var b= fun(0).fun(1).fun(2).fun(3);//undefined 0 1 2 + // var c= fun(0).fun(1);c.fun(2);c.fun(3);//undefined 0 1 1 + + //3.使用递归求到20的斐波那契数列之和 + function num(n) { + if (n==1||n==2) { + return 1 + }else{ + return num(n-1)+num(n-2) + } + } + function sum(n) { + if (n==0) { + return 0 + } + return num(n)+sum(n-1) + } + console.log(sum(20)); +``` \ No newline at end of file diff --git "a/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\345\216\237\345\236\213.md" "b/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\345\216\237\345\236\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..073618ba8799316752457f917e0d1af636409745 --- /dev/null +++ "b/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\345\216\237\345\236\213.md" @@ -0,0 +1,28 @@ +```js + +``` \ No newline at end of file diff --git "a/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\345\216\237\345\236\213\351\223\276&\347\273\247\346\211\277.md" "b/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\345\216\237\345\236\213\351\223\276&\347\273\247\346\211\277.md" new file mode 100644 index 0000000000000000000000000000000000000000..20ea5ba53b3d555f9d5d13eebb4c83e3fdd1f087 --- /dev/null +++ "b/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\345\216\237\345\236\213\351\223\276&\347\273\247\346\211\277.md" @@ -0,0 +1,84 @@ +``` + +``` \ No newline at end of file diff --git "a/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\347\273\247\346\211\277\344\270\213.md" "b/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\347\273\247\346\211\277\344\270\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..5bd3070e2143487d6fc7bb2d736458f0c3af3a70 --- /dev/null +++ "b/31\345\220\264\346\254\243\347\207\225/\344\275\234\344\270\232/\347\273\247\346\211\277\344\270\213.md" @@ -0,0 +1,17 @@ +``` + +``` \ No newline at end of file diff --git "a/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-03\345\216\237\345\236\213.md" "b/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-03\345\216\237\345\236\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..4931bcb2d9dc0c765f51f1db29ecfa2bc2d0a467 --- /dev/null +++ "b/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-03\345\216\237\345\236\213.md" @@ -0,0 +1,102 @@ +### 一,原型 + +#### 1,概念 + +- **函数**;函数有一个属性叫prototype,函数的这个原型指向一个对象,这个对象叫原型对象。这个原型对象有一个constructor属性,指向这个函数本身 +- **对象**;实例对象存在原型对象是proto(隐式原型),这个隐式原型有一个constructor属性,该属性指向创建该实例的构造函数 + +#### 2,优点 + +- 数据共享,节省内存空间 +- 为了实现继承 + +### 二,属性 + +#### 1,==prototype==属性 (显式原型) + +- **prototype 存在于构造函数中** (其实任意函数中都有,只是不是构造函数的时候prototype我们不关注而已) ,他指向了这个构造函数的原型对象 + + ``` + var fun = function () { } //创建一个空的构造函数 + //在函数原型中添加属性并赋值 + fun.prototype = { + name: '张三', + age: 25 + } + var a = new fun();//没有属性 + var b = function(){} + b.prototype = { + name:'李四', + age:20 + } + //a的原型中没有name属性就会往fun原型中查找 + //b的原型中有name属性就不会往fun原型中查找,直接调用b自己的name属性 + console.log(a.name, b.name); //张三 李四 + fun.prototype.name = '王五'; //更改fun函数原型当中的name属性值 + console.log(a.name, b.name); //王五 李四 + ``` + +#### 2,==constructor==属性 (隐式原型) + +- **constructor属性存在于原型对象中**,他指向了构造函数 + + ``` + function Obj() { } + function Test(obj) { + this.name = obj.name, + this.age = obj.age + } + Test.prototype = { + gender: '李四', + } + + //constructor:默认指向构造函数本身,可以指定为其他构造函数 + // Test.prototype.constructor = Obj; + // console.log(Test.prototype.constructor); 输出function Obj() { } + + function people() {} + console.log(people.prototype.constructor);//function people() {} + + function Person(){} + var person = new Person(); + console.log(person.prototype.constructor===Person.prototype);//true + ``` + +#### 3,==proto== 属性 + +- 用构造方法创建一个新的对象之后,这个对象中默认会有一个属性proto, 这个属性就指向了构造方法的原型对象 + + ``` + function Person(){} + var person = new Person(); + console.log(person._proto_===Person.prototype);//true + ``` + +#### 4,总结 + +- 函数的prototype属性: 在定义函数时自动添加的, 默认值是一个空Object对象 +- 对象的proto属性: 创建对象时自动添加的, 默认值为构造函数的prototype属性值 +- 可以直接操作显式原型, 但不能直接操作隐式原型(ES6之前) + +### 三、列 + +``` + function obj(){} + + obj.prototype.name='张三' + obj.prototype.age= '18' + + var obj1=new obj(); + + console.log(obj1.name) //会输出张三 + + var obj2=new obj(); //new创建一个对象obj2 + + obj1.name='李四'; + + console.log(obj1.name) // obj1的name 会输出李四 + + console.log(obj2.name) // obj2的name 会输出张三 + + //由于不能修改原型中的值,则这种方法就直接在obj1中添加了一个新的属性name,然后在obj2中无法访问 +``` \ No newline at end of file diff --git "a/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-07\345\216\237\345\236\213\351\223\276.md" "b/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-07\345\216\237\345\236\213\351\223\276.md" new file mode 100644 index 0000000000000000000000000000000000000000..0f935992f167c5b3f6cfc6c3eb2f25f697c0ad35 --- /dev/null +++ "b/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-07\345\216\237\345\236\213\351\223\276.md" @@ -0,0 +1,106 @@ +### 一,原型链 + +#### 1,概念 + +- 让原型对象等于另一个类型的实例,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条(所有的原型构成了一个链条) + +#### 2,特点 + +- 原型链的顶层---Object(所有对象的父类),如果再往上找,就是null +- 原型重写与修改 Test.prototype = {} Test.prototype.name = '' +- 原型链,**所有子级(自己没有)会引用其父级的属性**, **子级一般来说不能修改父级属性,(除非是引用)** +- 绝大数对象最终都会继承自Object.prototype, 除非使用Object.create(null) + +``` + var Professor = function () { + } + Professor.prototype = { + name: '教授', + //如果原型中有引用值,那么子集能改掉,改的是引用值对应地址中的值 + info: { + age: 60 + } + } + var professor = new Professor() + + + var Teacher = function () { } + Teacher.prototype = professor + Teacher.prototype.tname = '教师' + var teacher = new Teacher(); + + var Student = function () { } + Student.prototype = teacher + Student.prototype.sname = '学生' + var student = new Student(); +``` + +### 二,原型链操作 + +- **子级没权限 增/改/删 父级的属性,除非父级的属性是引用值** + +#### 1,增加;在需要增加的原型中直接点出这个增加的属性以及赋值 + +``` + //增加--给学生增加一个性别属性 + Student.prototype.sgender = '女'; + console.log(Student.prototype.sgender); +``` + +#### 2,修改 + +- 子类不能修改掉父类的属性值,除非这个属性值是引用类型 + +``` + //把刚刚增加的Student中的性别改成男 + Student.prototype.sgender = ['男'] + console.log(Student.prototype.sgender); +``` + +#### 3,删除(delete) + +- delete删除对象属性,delete删除不了变量及[原型链](https://gitee.com/link?target=https%3A%2F%2Fso.csdn.net%2Fso%2Fsearch%3Fq%3D%E5%8E%9F%E5%9E%8B%E9%93%BE%26spm%3D1001.2101.3001.7020)中的变量 + +``` + //删除Student中的sgender属性 + delete Student.prototype.sgender; + console.log(Student.prototype.sgender);//undefined +``` + +#### 4,查询;console.log(); + +- 如果查询的对应原型中没有这个属性,则往上一级查找,直到找到这个属性值(就近原则) + +``` + var Professor = function () { + } + Professor.prototype = { + name: '教授', + //如果原型中有引用值,那么子集能改掉,改的是引用值对应地址中的值 + info: { + age: 60 + } + } + var professor = new Professor() + + + var Teacher = function () { } + Teacher.prototype = professor + Teacher.prototype.tname = '教师' + var teacher = new Teacher(); + + var Student = function () { } + Student.prototype = teacher + Student.prototype.sname = '学生' + var student = new Student(); + //查询 + console.log(professor.prototype.name);//教授 + console.log(Teacher.prototype.tname);//教师 + console.log(Student.prototype.sname);//学生 +``` + +#### 全部(原型);create + +``` +var obj = Object.create(null); //No properties +``` \ No newline at end of file diff --git "a/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-07\347\273\247\346\211\277.md" "b/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-07\347\273\247\346\211\277.md" new file mode 100644 index 0000000000000000000000000000000000000000..c0ab41c5d0517d0e5cf17b52119413331e877390 --- /dev/null +++ "b/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-07\347\273\247\346\211\277.md" @@ -0,0 +1,89 @@ +### 一,继承 + +#### 1.传统形式-->原型链 + +- 弊端--过多的继承了没用的属性 + +#### 2.构造函数继承 + +##### 2.1,弊端 + +- 不能继承借用构造函数的原型 +- 每次构造函数都要多走一个函数 +- 子类只能继承父类的属性,不能继承父类的方法 + +``` + function Person(name, age) { + this.name = name; + this.age = age; + } + + function Student(score, name, age, sayHello) { + Person.call(this, name, age, sayHello); + this.score = score; + } + Student.prototype.study = function() { + console.log('这次的考试成绩是' + this.score + '分'); + } + + var student = new Student(80, 'ABC', 20); + var person = new Person('ABC', 45); + Person.prototype.sayHello = function() { + console.log('你好,我叫' + this.name + "今年" + this.age + "岁了"); + } + person.sayHello();//可以正确输出,但是student.sayHelllo()不行 + console.log(student.name); +``` + +#### 3.共享原型 + +- 不能随便改动自己的原型 +- 共享一个原型,你改动,我改动 + +``` +Teacher.prototype.gender = '男'; +Function Teacher(){} +FUnction Student(){} +//创建共享原型 +function inherit(Target,Origin){ + Target.prototype = Origin.prototype; +} + +//inherit(Student,Teacher) +var son = new Son(); +``` + +#### 4.圣杯模式 + +- 圣杯模式的出现和思路与浅层克隆和深层克隆问题很相似 +- 圣杯模式子类可以继承父类的属性与方法 + +##### 4.1,步骤 + +- 引入了一个中间的媒介,利用空对象作为中介,(空对象几乎不占内存) +- 让空对象的原型指向父亲的原型 +- 让儿子的原型不是直接指向父亲,而是指向空对象的实例,这样也能继承到父亲上的属性,改变时又不会互相影响 +- 最后记得将儿子的构造器归位就可以 + +``` + function Father(){} + Father.prototype.sex = 'male'; + function Son(){} + + function inherit(Target,Origin){ + function F(){} //私有构造函数 + //1.私有构造函数先继承 + F.prototype = Origin.prototype; + //2.再来实例化Target + Target.prototype = new F(); + //3.归位 + Target.prototype.constructor = Target; + //可有可无:超类uber + Target.prototype.uber = Origin.prototype; + } + + inherit(Son,Father); + console.log(Son.prototype.constructor); + var son = new Son(); + } +``` \ No newline at end of file diff --git "a/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-13\347\273\247\346\211\277\344\270\213.md" "b/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-13\347\273\247\346\211\277\344\270\213.md" new file mode 100644 index 0000000000000000000000000000000000000000..482a2dd1391ea3cc5e93cdcd7603eca32ce460b2 --- /dev/null +++ "b/31\345\220\264\346\254\243\347\207\225/\347\254\224\350\256\260/2022-11-13\347\273\247\346\211\277\344\270\213.md" @@ -0,0 +1,174 @@ +### 进阶圣杯模式 + +- 在立即执行函数里返回圣杯模式 + +``` + function Person() {} + function Student() {} + var inherit = (function() { + return function(Target, Origin) { + function f() {} + f.prototype = Origin.prototype; + Target.prototype = new f(); + Target.prototype.constructor = Target; + } + }()) + inherit(Student, Person); + var person = new Person(); + Person.prototype.name = 'ABC'; + Person.prototype.age = 20; + Person.prototype.sayHello = function() { + console.log('你好,我叫' + this.name + "今年" + this.age + "岁了"); + } + person.sayHello(); + + var student = new Student(); + Student.prototype.score = 81; + Student.prototype.study = function() { + console.log('我的考试成绩是' + this.score + '分'); + } + console.log(student.name); + student.study(); + student.sayHello(); +``` + +### class语法 + +- 基于原型和原型链, 默认在use strict(严格模式) 的模式下进行的 +- 子类通过extends继承父类,继承时一定要有super()函数 +- super函数的作用就是继承父类的属性 + +``` +//父类 +class Shape{ + constructor(){ //装属性的空间 + this.pro = '图形'; + } + //自定义Draw方法 + Draw(){ + console.log('我是一个图形'); + } +} +//子类 +class Circle extends Shape{ + constructor(center,r){//center与r是传进来的参数 + super(); //必填 + this.r = r; + this.x = center[0];//把center当做数组,x是下标为0的center数组的值 + this.y = center[1]; + } + //自定义getArea方法 + getArea(){ + return (Math.PI*this.r*this.r).toFixed(2); //保留小数几位 + } + //更改x,y的值用move + move(x,y){ + this.x += x; + this.y += y; + } + //自定义方法输出 + position(){ + console.log('我的位置在'+this.x+','+this.y); + } +} + +var circle =new Circle([0,0],5); +console.log(circle.getArea()); +console.log(circle.pro); +circle.position(); +circle.move(5,5); +circle.position(); +``` + +### 链式调用 + +- 每一个方法都要返回(return this) +- 输出可以直接接着点出这个方法 + +``` +var plan = { + mon: function () { + console.log('吃饭'); + return this; + }, + tue: function () { + console.log('睡觉'); + return this; + }, + wed: function () { + console.log('打豆豆'); + return this; + }, + thu: function () { + console.log('学习'); + return this; + }, + fri: function () { + console.log('锻炼'); + return this; + }, + sat: function () { + console.log('逛街'); + return this; + } +} +//输出 +plan.mon().tue().wed().thu().fri().sat(); +``` + + + +### for in 与 for of 的区别 + +#### 1,for of(遍历属性对应的值,没有key) + +``` +for (let e of[1, 2, 34, 4, 5]) { + console.log(e); + } +``` + +#### 2,for in (遍历键值对,key,value) + +- 输出顺序不固定 + +``` +var obj ={ + 'No1' : '第一', + 'No2' : '第二', + 'No3' : '第三' +} +for(let e in obj){ + console.log(e+':'+obj[e]); +} +//输出'No1' : '第一', + // 'No2' : '第二', + // 'No3' : '第三' +``` + +### in 和 hasownProperty() 的用法 + +#### 1,in(可以找自己的属性和原型里面的属性) + +``` +var obj = { + name:'白熊', + age:18 +} +obj.__proto__.gender = '女'; + + console.log('name' in obj); //true + console.log('gender' in obj); //true +``` + +#### 2,hasOwnProperty()(只能找自己的属性,找不到原型里面的属性) + +``` +var obj = { + name:'哒哒', + age:18 +} +obj.__proto__.gender = '女'; + console.log(obj.hasOwnProperty('name'));//true +console.log(obj.hasOwnProperty('gender'));//false +``` \ No newline at end of file