diff --git "a/\350\214\203\351\233\205\346\254\242/\344\275\234\344\270\232/10.12 \345\257\271\350\261\241\344\275\234\344\270\232.md" "b/\350\214\203\351\233\205\346\254\242/\344\275\234\344\270\232/10.12 \345\257\271\350\261\241\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..f2ac7949bc81f874f619adabd9e80fe4cbfd2ad6 --- /dev/null +++ "b/\350\214\203\351\233\205\346\254\242/\344\275\234\344\270\232/10.12 \345\257\271\350\261\241\344\275\234\344\270\232.md" @@ -0,0 +1,115 @@ +#### 题目 + +```js + +``` + +我们根据需要,可以students.prototype 属性指定新的对象,来作为students的原型对象。但是这个时候有个问题,新的对象的constructor属性则不再指向students构造函数了。 + +3. _ **proto** _ 属性 + +用构造方法创建一个新的对象之后,这个对象中默认会有一个属性__proto__, 这个属性就指向了构造方法的原型对象 \ No newline at end of file diff --git "a/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/10.27 \345\216\237\345\236\213\351\223\276.md" "b/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/10.27 \345\216\237\345\236\213\351\223\276.md" new file mode 100644 index 0000000000000000000000000000000000000000..0f5234b2feaedf7c14fd0fffa4d76e56816eb5ce --- /dev/null +++ "b/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/10.27 \345\216\237\345\236\213\351\223\276.md" @@ -0,0 +1,49 @@ +## 原型链 + +所有的原型构成了一个链条,这个链条我们称之为原型链。 + +当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的**prototype**,如果还没有找到就会再在构造函数的**prototype**的__proto__中查找,这样一层一层向上查找就会形成一个链式结构 + +子级没权限 增/改/删 父级的属性,除非父级的属性是引用值 + +```js +var Test = function () { + name:'张静' +} +function Test(){ + this.name = '张静' +} +Test.prototype = { + name:'安可', + sayHi: function(){ + console.log('Hello,I am'+this.name); + } +} +var test = new Test() +test.sayHi(); +Test.prototype.sayHi(); +``` + +#### 示例 + +```js + 例子: +Person.prototype.lastName = "u"; + function Person(name) { + this.name = name; + } + var person = new Person('F'); +// 想要修改lastName必须通过原型来修改,Person.prototype.lastName = " "来修改 +// 如果直接在构造函数Person.lastName来修改,只是在构造函数中增加一个lastName属性 +// 通过对象来修改原型属性是不可能的 +``` + +#### 总结 + + 1.原型__proto__, prototype, constuctor + + 2.原型重写与修改 Test.prototype = {} Test.prototype.name = '' + + 3.原型链,所有子级(自己没有)会引用其父级的属性, 子级一般来说不能修改父级属性,(除非是引用) + + 4.绝大数对象最终都会继承自Object.prototype, 除非使用Object.create(null) \ No newline at end of file diff --git "a/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/10.31 \347\273\247\346\211\277.md" "b/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/10.31 \347\273\247\346\211\277.md" new file mode 100644 index 0000000000000000000000000000000000000000..d1b6eaf419f6c10ee3f4f5a309a066c4c6200bb6 --- /dev/null +++ "b/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/10.31 \347\273\247\346\211\277.md" @@ -0,0 +1,80 @@ +## 继承 + +#### 原型链继承 + +原型链继承是ECMAScript的主要继承方式(传统形式)。其基本思想就是通过原型继承多个引用类型的属性和方法。 + +```js +function Personal () { +} +Personal.prototype = { + constructor:Personal , + name:'hhh', + sayName:function () {} +} +var p = new Personal(); +p.name +p.sayName() +``` + +#### 构造函数继承 + +call和apply方法,将父类构造函数绑定在子类上 + +```js +//父类 +function Person(name, age, sex) { + this.name = name; + this.age = age; + this.sex = sex; +} +//子类 +function Student(name, age, sex, grade) { + //call thi默认指向window + Person.call(this, name, age, sex); + //apply + Person.call(this, [name, age, sex]); + this.grade = grade; +} +var student = new Student('张三',29,'男',2022); +console.log(student.name); +``` + +#### 共享原型 + +可复用成员应该转移到原型中而不是放置在this中。因此,处于继承的目的,任何值得继承的东西都应该放置在原型中实现。所以,可以仅将子对象的原型与父对象的原型设置为相同即可。这种模式能够简短而迅速地原型链查询。 + +```js +function Father(){} +Father.prototype.sex = 'male'; +function Son(){} +//Target:目标 Origin:起源 +function inherit(Target,Origin){ + Target.prototype = Origin.prototype; +} +inherit(Son,Father); +var son = new Son(); +Son.prototype.skill = 'js'; +console.log(son.__proto__.sex); +console.log(son.skill); +var father = new Father(); +console.log(father.skill); +``` + +#### 圣杯模式 + +```js +var inherit = (function(){ + //闭包可以实现属性私有化 + var F = function(){}; + return function(Target,Origin){ + F.prototype = Origin.prototype; + Target.prototype = new F(); + Target.prototype.constructor = Target; //归位 + Target.prototype.uber = Origin.prototype; //超类 + } +}()) +inherit(Son,Father) +var son = new Son(); +var father = new Father(); +``` \ No newline at end of file diff --git "a/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/11.1 Class\350\257\255\346\263\225\347\263\226\347\273\247\346\211\277.md" "b/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/11.1 Class\350\257\255\346\263\225\347\263\226\347\273\247\346\211\277.md" new file mode 100644 index 0000000000000000000000000000000000000000..ce81fcd354f805850c675c66b222175a50bd0e88 --- /dev/null +++ "b/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/11.1 Class\350\257\255\346\263\225\347\263\226\347\273\247\346\211\277.md" @@ -0,0 +1,29 @@ +### Class语法糖继承 + +关键字class从ES6开始正式被引入到JavaScript中。class的目的就是让定义类更简单。 + +class的定义包含了构造函数constructor和定义在原型对象上的函数hello()(注意没有function关键字),这样就避免了Student.prototype.hello = function () {...}这样分散的代码。 + +用class定义对象的另一个巨大的好处是继承更方便了。想一想我们从Student派生一个PrimaryStudent需要编写的代码量。现在,原型继承的中间对象,原型对象的构造函数等等都不需要考虑了,直接通过extends来实现: + +``` +//使用extends继承 +class PrimaryStudent extends Student { + //构造器 + constructor(name, grade) { + super(name); //记得用super调用父类的构造方法!(constructor) + this.grade = grade; + } + //方法 + myGrade() { + alert('I am at grade ' + this.grade); + } +} +``` + +注意PrimaryStudent的定义也是class关键字实现的,而extends则表示原型链对象来自Student。子类的构造函数可能会与父类不太相同,例如,PrimaryStudent需要name和grade两个参数,并且需要通过super(name)来调用父类的构造函数,否则父类的name属性无法正常初始化。 + +PrimaryStudent已经自动获得了父类Student的hello方法,我们又在子类中定义了新的myGrade方法。 + +**ES6引入的class和原有的JavaScript原型继承实际上没有任何区别,class的作用就是让JavaScript引擎去实现原来需要我们自己编写的原型链代码。简而言之,用class的好处就是极大地简化了原型链代码。** + diff --git "a/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/11.14 DOM.md" "b/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/11.14 DOM.md" new file mode 100644 index 0000000000000000000000000000000000000000..1d46e26b846e0742fc87e88c43388fb19904c49a --- /dev/null +++ "b/\350\214\203\351\233\205\346\254\242/\347\254\224\350\256\260/11.14 DOM.md" @@ -0,0 +1,247 @@ +## 元素获取 + +#### 获取特殊元素(body、html) + +``` +//html头部里的title 输出Document + console.log(document.title); +//输出html头部里的全部 + console.log(document.head); +//全部html + console.log(document.documentElement); +``` + +#### 根据选择器获取元素 + +**document.querySelector():通过 css 中的选择器去选取第一个符合条件的标签元素** + +**document.querySelectorAll():通过 css 中的选择器去选取所有符合条件的标签元素集合(伪数组)** + +**使用时注意:** + +浏览器兼容问题:不支持 IE8 + +需要将 js 代码写在 html 结构之后;不会动态增加 + +### 根据类名获取元素 + +**方法:document.getElementsByClassName()** + +**返回:HTMLCollection集合 **即class 属性值相同的元素对象组成的动态集合(伪数组) + +**参数:字符串类型的 class 属性值** + +此方法内部获取的元素是动态增加的 + +\###4根据 name 获取元素 + +**方法: document.getElementsByName()** + +**参数:字符串类型的 name 属性值。** + +**返回:返回的是NodeList** 即name 属性值相同的元素对象组成的集合(伪数组形式)。 + +不建议使用:在 IE 和 Opera 中有兼容问题,会多选中 id 属性值相同的元素 + +\###5根据标签名获取元素 + +**方法:document.getElementsByTagName()** + +**参数:字符串类型的标签名。** + +**返回:返回的是HTMLCollection集合** 即同名的元素对象组成的集合(以伪数组的形式存储)。 + +根据 id 获取元素 + +**方法: document.getElementById()** + +**参数:字符串类型的 id 的属性值。** + +**返回值:对应 id 名的元素对象。** + +***注意:*** ***代码执行顺序,如果 js 在 html 结构之前,会导致结构未加载,不能获取对应id的元素***** + +### 7子/父/兄弟节点获取 + +| 属性 | 内容 | +| ------------------------------------------------------- | ---------------------------------- | +| document.body.**childNodes** | 获取body的子节点 | +| document.body.**childElementCount** | 获取body的子节点长度 | +| document.body.**firstChild** | 返回第一个**子节点(**包含文本节点) | +| document.body.**firstElementChild** | 返回第一个**元素子节点** | +| document.body.**lastChild** | 返回最后一个**字节点** | +| document.body.**lastElementChild** | 返回最后一个**元素子节点** | +| document.body.**children[0].children[0].parentNode** | 返回父元素,两种方法效果一样 | +| document.body.**children[0].children[0].parentElement** | 返回父元素,两种方法效果一样 | +| document.body.**children[0].nextSibling** | 下一个兄弟节点(包含文本节点) | +| document.body.**children[0].nextElementSibling** | 下一个元素兄弟节点 | +| document.body.**children[1].previousSibling** | 上一个兄弟节点(包含文本节点); | +| document.body.**children[1].previousElementSibling** | 上一个元素兄弟节点 | + +| 方法 | 内容 | +| ---------------------------------- | ------------------------------------------- | +| document.body.**hasChildNodes();** | 判断是否有子节点,有返回true,没有返回false | +| | | + +## 节点层数 + +节点定义:DOM的最小组成单位叫做节点(node),文档的树形结构(DOM树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。 + +### 节点类型 + +| 节点 | 值 | 释义 | 对应常量 | +| ----------------------------- | ---- | ------------------------------------------------------------ | --------------------------- | +| 文档节点 Document | 9 | 整个HTML文档document对象作为window对象的属性存在的,不用获取可以直接使用 | Node.DOCUMENT_NODE | +| 文档类型节点 DocumentType | 10 | doctype标签 | Node.DOCUMENT_TYPE_NODE | +| 元素节点 Element | 1 | HTML文档中的HTML标签 | Node.ELEMENT_NODE | +| 文本节点 Text | 3 | HTML标签中的文本内容 | Node.TEXT_NODE | +| 注释节点 Comment | 8 | | Node.COMMENT_NODE | +| 文档片断节点 DocumentFragment | 11 | | Node.DOCUMENT_FRAGMENT_NODE | +| 属性节点 Attribute | 2 | 元素的属性 表示的是标签中的一个一个的属性,这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分 | Node.ATTRIBUTE_NODE | + +### 节点关系 + +- 父节点关系(parentNode):直接的那个上级节点 + +- 子节点关系(childNode):直接的下级节点 (属性;firstChild(第一个子节点),lastChild(最后一个子节点)) + +- 同级节点关系(sibling):拥有同一父节点的节点 (属性;nextSibling(紧邻在后的那个同级节点),previousSibling(紧邻在前的那个同级节点)) + +- 遍历节点 + + ``` + console.log(document.body.childNodes); + for (var i = 0; i < document.body.childNodes.length; i++) { + node = document.body.childNodes[i]; + console.log(node.nodeType); //节点类型 + console.log(node.nodeName); //节点名称 + console.log(node.nodeValue); //节点值 + } + ``` + +### 节点树 + + + +## DOM级别 + +1. DOM 0 级事件: onclick + +2. DOM 2 级事件:EventTarget.addEventListener(type, listener, useCapture) + +3. | 参数 | 描述 | + | ------------ | ------------------------------------------------------------ | + | *event* | **必须**。字符串,指定**事件名**。 **注意:** 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。 | + | *function* | **必须**。指定要事件触发时执行的函数。 当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, "click" 事件属于 MouseEvent(鼠标事件) 对象。 | + | *useCapture* | **可选**。布尔值,指定事件是否在捕获或冒泡阶段执行。 可能值: true - 事件句柄在捕获阶段执行 false- false- 默认。事件句柄在冒泡阶段执行 | + +## Node + +| | 元素节点 | 属性节点 | 文本节点 | 注释节点 | +| --------- | -------- | -------- | -------- | ---------- | +| nodeType | 1 | 2 | 3 | 8 | +| nodeName | 元素名 | 属性名 | #text | #comment | +| nodeValue | null | 属性值 | 文本值 | 注释的文本 | + +## 操作(增删改子节点) + +``` + + +
+ + + +...
+var p = document.getElementById('p-id'); +// 设置文本为abc: +p.innerHTML = 'ABC'; //ABC
+// 设置HTML: +p.innerHTML = 'ABC...
的内部结构已修改 +id.innerHTML='123'//可以解析HTML文本值 +``` + +用innerHTML时要注意,是否需要写入HTML。如果写入的字符串是通过网络拿到了,要注意对字符编码来避免XSS攻击。 + +**第二种是修改innerText或textContent属性,这样可以自动对字符串进行HTML编码,保证无法设置任何HTML标签**: + +``` +// 获取...
+var p = document.getElementById('p-id'); +// 修改文本的值: +p.innerText = ''; +// HTML被自动编码,无法设置一个 + + + +