<script>这里面不可以出现‘</script>’</script>
// 这样不可以
alert('</script>')
// 非要写,可以这样
alert('<\/script>')
// type属性:脚本语言的内容类型
<script type="module">
import { createApp } from '/@modules/vue'
import App from '/App.vue'
createApp(App).mount('#app')
</script>
<script type="text/javascript"></script>
javascript开启严格模式,可以在代码文件 顶部添加如下代码:
"use strict";
指定函数在严格模式下执行;
function doSomething() {
"use strict";
// 函数体
}
定义没有赋值、没有定义;都是undefined
var message
// var age
typeof message 'undefined'
typeof age 'undefined'
// null 是空对象
typeof null 'object';
// 八进制数字,第一个数字是0,后面的数字不能大于8
070 === 56
079 === 79
08 === 8
// 16进制数字,前面是0x,后面是(0~9及A~F)字母不区分大小
0xA === 10
0x1f === 31
0xg // 报错
// e 科学计数法;e后面是正整数,表示有几个0;负整数,表示几个小数点
2e3 === 2000
2e-3 === 0.002
// 永远不要直接计算浮点数值;先放大 一定倍数 到整数,再计算,再缩小 放大的倍数
0.1 + 0.2 === 0.3000000000000004
// 调用isNaN,函数会自动先把参数转成数字
isNaN(Number(str)) === isNaN(str)
// 所以,如下操作
isNaN('10') === false
isNaN(true) === false
isNaN('abc') === true
Number() 可以转换任何数据类型;转成功就是数字,失败是NaN
parseInt()和parseFloat() 只能转字符串
特殊说明;Number("") => 0; parseInt("") => NaN
// label 用于退出外面的for循环
outfor:
for(var i=0; i < 10; i++) {
console.log('out:'+i)
for (var j=0; j < 10; j++) {
console.log('in:'+j)
if (i == 5&& j==5) {
break outfor;
}
}
}
// with 省略 对象重复写(严格模式下,不允许使用with语句)
with (location) {
gs = host;
url = href
}
// switch 可以这么玩
var num = 25;
switch (true) {
case num < 0:
alert('less than 0.');
break;
case num >=0 && num <=10:
alert('between 0 and 10');
break;
default:
}
// 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。
//虽然我们编写代码无法访问这个对象,但解析器在处理数据时会在后台使用它。
// 作用域链;从函数内而外,一层层往外找
var person = {
5: '数字属性会自动转成字符串'
}
var arr = [];
arr[20] = '和对象一样,设置一个数字属性。不一定要从0开始设置;只不过会多一个length属性'
{
20: '和对象一样,设置一个数字属性。不一定要从0开始设置;只不过会多一个length属性'
length: 21
}
// 2这个属性不在arr数组(对象)里
arr[2] === undefined
var arr = [1,5,12,9]
// sort 方法,调用每个数组项的toString(),以确定排序
arr.sort(); // [1, 12, 5, 9]
// 这样也多时候是有问题的。所有支持函数,函数有两个参数。第一个位于第二个前面返回负数,相等为0,第一个位于第二个后面返回正数。
arr.sort(function (a, b) {
if (a < b) return -1;
else if (a > b) return 1;
else return 0;
})
indexof 和 lastIndexOf。都支持两个参数 indexOf(要查找的值,查找的起始位置(可选,默认0))
var arr = [0,1,2,3,4,5,2,5]
arr.indexOf(2,3); // 从第三项开始找2.找到为止
var arr = [0,1,2,3,4,5,2,5]
// every每项都满足条件,返回true
arr.every(function (item, index, array) {
return item > 2
});
// some有一项都满足条件,返回true
arr.some(function (item, index, array) {
return item > 2
});
Date.parse('2021-1-1') // 字符串转时间戳
// 直接new Date本来参数一定要时间戳。如果是字符串,后台自动会调用Date.parse
new Date('2021-1-1') === new Date(Date.parse('2021-1-1'))
// callee;拥有这个arguments的函数的引用
function fn() {
console.log(arguments.callee) // 就是fn本身
}
// caller; 调用当前函数的函数的引用
function inner() {
console.log(inner.caller); // outer
console.log(arguments.callee.caller); //outer
}
function outer() {
inner();
}
outer();
// 关于this;函数谁调用,this就是谁,函数名 仅仅是一个包含指针的变量而已
var color = 'red', o = {};
o.sayColor = function () {
console.log(this.color)
}
function fn(sayColor) {
sayColor();
}
fn(o.sayColor); // 'red';
/**执行了这个函数
* function () {
console.log(this.color)
}
*/
/**
// 函数的length。返回定义的参数个数
function fn(a, b,c){}
fn.length // 3
// apply,第一个参数,是设置函数体内的this,第二个参数是数组,也就是函数的arguments
function fn (num1, num2) {
console.log(this);
return num1+num2;
}
fn.apply({age: 30}, [1,2]); // {age: 30}; 3;
// bind,该方法会创建一个新的函数实例,并且给函数体内指定this。但不会执行函数。
var newFn = fn.bind({age: 30})
newFn(1,2); // {age: 30}; 3;
// 基本包装类型;每当读取一个基本类型值的时候,后台会创建一个对于的基本包装类型对象,让我们可以调用一些方法来操作基本类型值。
var str = 'some text';
str.substr(1); // 相当于 new String(str).substr(1)
// 也可以显式的创建基本包装类型的对象,但是那样,会让人难以分清自己是在处理‘基本类型’还是‘引用类型’
new Object('abc') === new String('abc')
new Object(333) === new Number(333)
new String('abc') 和 String('abc') 不一样
'E'.charCodeAt(0); // 69'
String.fromCharCode(69); // 'E'
var arr = [1,3,5,2,9]
Math.max.apply(Math, arr);
var o = new Object();
Object.prototype.isPrototypeOf(o); // Object.prototype 在不在o的内部属性[[Prototype]]中
Object.getPrototypeOf(o) === Object.prototype; // Object身上有个方法getPrototypeOf,来访问实力化对象o的内部属性[[Prototype]]
person1.hasOwnProperty('name'); // name 是不是person1自己的属性;如果是person1构造函数原型的属性返回false
'name' in person1; // 无论'name'在person1中,还是其构造函数的原型中。都返回true
// 联合 hasOwnProperty和in,确定一个属性是在原型中
function hasPrototypeProperty(object, name) {
return (name in object) && !object.hasOwnProperty(name);
}
Object.getOwnPropertyNames(Object.prototype); // 返回被访问对象自己身上的所有属性,无论它是否可枚举
Object.keys(person1); // 返回被访问对象自己身上的,可枚举属性([[Enumerable]]为true的属性)
Person.prototype = {
constructor: Person, // 这样主动设置的constructor,是可枚举的([[Enumerable]]为true)
name: 'kp',
sayName() {}
}
// 正确设置constructor方法
Object.defineProperty(Person.prototype, 'constructor', {
enumerable: false,
value: Person
})
实例中访问构造函数原型的指针,指向的是构造函数原型,不是构造函数; 所以重写构造函数原型对象,【实例对象】访问还是原来的【原型对象】。
![](https://img.haomeiwen.com/i15197612/25ee8497094eacec.png)
image.png
function Person() {}
Person.prototype.name = 'kp'
var p = new Person();
p.name; // kp
p.__proto__; // {name: "kp", constructor: ƒ}
Person.prototype = {
constructor: Person,
age: 88
}
p.age; // undefined
// 构造函数的原型是变了,但是实例对象身上的__proto__,还是指向原来的那个原型对象
p.constructor.prototype; // {constructor: ƒ, age: 88}
p.__proto__; // {name: "kp", constructor: ƒ}
// 改变原型后,再实例化一个对象。对象访问最新的原型。
var p2 = new Person();
p2.age; // 88
p2.name; // undefined
p.__proto__; // {constructor: ƒ, age: 88}
p.constructor.prototype; // {constructor: ƒ, age: 88}
p instanceof Person; // p 是Person的实例吗?
p instanceof Object; // p 是Object的实例吗?
Person.prototype.isPrototypeOf(p); // Person.prototype是p的原型吗?
Object.prototype.isPrototypeOf(p); // Object.prototype是p的原型吗?
// 组合继承 = 原型链继承 + 构造函数继承
function Sup(name) {
this.name = name;
}
Sup.prototype.sayName = function () {
console.log(this.name);
}
function Sub(name, age) {
Sup.call(this, name); // 构造函数继承
this.age = age;
}
Sub.prototype = new Sup(); // 原型链继承;继承方法Sup.prototype.sayName
Sub.prototype.addAge = function () {
return ++this.age;
}
// 匿名函数可以立刻执行
var fn = function () {
return 'abc';
}();
// 函数申明不可以立刻执行,会报错;可能和申命 提升有关系
function fn() {
return 'abc';
}();
只有 domain 是可以设置的。但由于安全方面的限制,也并非可以给 domain 设
置任何值。如果 URL 中包含一个子域名,例如 p2p.wrox.com,那么就只能将 domain 设置为"wrox.com"
(URL 中包含"www",如 www.wrox.com 时,也是如此)。不能将这个属性设置为 URL 中不包含的域,
如下面的例子所示。
//假设页面来自 p2p.wrox.com 域
document.domain = "wrox.com"; // 成功
document.domain = "nczonline.net"; // 出错!
当页面中包含来自其他子域的框架或内嵌框架时,能够设置 document.domain 就非常方便了。由
于跨域安全限制,来自不同子域的页面无法通过 JavaScript 通信。而通过将每个页面的
document.domain 设置为相同的值,这些页面就可以互相访问对方包含的 JavaScript 对象了。例如,
假设有一个页面加载自 www.wrox.com,其中包含一个内嵌框架,框架内的页面加载自 p2p.wrox.com。
由于 document.domain 字符串不一样,内外两个页面之间无法相互访问对方的 JavaScript 对象。但如
果将这两个页面的 document.domain 值都设置为"wrox.com",它们之间就可以通信了。
document.referrer // "https://www.feishu.cn/" 从哪个域名跳转过来的
// 注释节点 nodeType:8
var comment = document.createComment("A comment");
comment.data === 'A comment';
// DocumentFragment类型; nodeType 的值为 11; 是一种“轻量级”的文档
var fragment = document.createDocumentFragment();
var ul = document.getElementById("myList");
var li = null;
for (var i=0; i < 3; i++){
li = document.createElement("li");
li.appendChild(document.createTextNode("Item " + (i+1)));
fragment.appendChild(li);
}
// 此时,fragment的所有子节点都被删除并转移到了<ul>元素中
ul.appendChild(fragment); // // fragment是一个容器,3个li一次性添加到ul里面.
html范围选择,查看12.4 范围 【350页】
// 这个event是自动插入的
<input type="button" value="Click Me" onclick="alert(event.type)"/>
<form method="post">
<input type="text" name="username" value="">
<input type="button" value="Echo Username" onclick="alert(username.value)">
</form>
// onclick内部处理,如下:
function(){
with(document){
with(this.form){
with(this){
//元素属性值
}
}
}
}
var btn = document.getElementById("myBtn");
// 以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。
btn.onclick = function(){
alert(this.id); //"myBtn"
};
// addEventListener()和 removeEventListener() 最后这个布尔值参数如果是 true,表示在捕获阶段调用事件处理程序;如果是 false,表示在冒泡阶段调用事件处理程序。
// 如下代码,点击li;先弹出 ul,在弹出 li
<ul><li></li></ul>
ul.addEventListener('click', function () {
alert('ul');
}, true);
li.addEventListener('click', function () {
alert('li');
}, true);
事件对象的 eventPhase 属性,可以用来确定事件当前正位于事件流的哪个阶段。如果是在捕获阶
段调用的事件处理程序,那么 eventPhase 等于 1;如果事件处理程序处于目标对象上,则 eventPhase 等于 2;如果是在冒泡阶段调用的事件处理程序,eventPhase 等于 3。这里要注意的是,尽管
“处于目标”发生在冒泡阶段,但 eventPhase 仍然一直等于 2。来看下面的例子。
var btn = document.getElementById("myBtn");
btn.onclick = function(event){
alert(event.eventPhase); //2
};
document.body.addEventListener("click", function(event){
alert(event.eventPhase); //1
}, true);
document.body.onclick = function(event){
alert(event.eventPhase); //3
};
DOMContentLoaded 事件则在形成完整的 DOM 树之后就会触发,
不理会图像、JavaScript 文件、CSS 文件或其他资源是否已经下载完毕。
对于不支持 DOMContentLoaded 的浏览器,我们建议在页面加载期间设置一个时间为 0 毫秒的超
时调用,如下面的例子所示。
setTimeout(function(){
//在此添加事件处理程序
}, 0);
这段代码的实际意思就是:“在当前 JavaScript 处理完成后立即运行这个函数。”在页面下载和构建
期间,只有一个 JavaScript 处理过程,因此超时调用会在该过程结束时立即触发。
网友评论