window.navigator 对象包含有关访问者浏览器的信息。
window.navigator 对象在编写时可不使用 window 这个前缀。
<script>
txt = "<p>浏览器代号: " + navigator.appCodeName + "</p>";
txt+= "<p>浏览器名称: " + navigator.appName + "</p>";
txt+= "<p>浏览器版本: " + navigator.appVersion + "</p>";
txt+= "<p>启用Cookies: " + navigator.cookieEnabled + "</p>";
txt+= "<p>硬件平台: " + navigator.platform + "</p>";
txt+= "<p>用户代理: " + navigator.userAgent + "</p>";
txt+= "<p>用户代理语言: " + navigator.language + "</p>";
document.getElementById("example").innerHTML=txt;
</script>
▲js代码执行顺序
1.执行时间
window.onload必须等到页面内包括图片的所有元素加载完毕后才能执行。
$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。
2.编写个数不同
window.onload不能同时编写多个,如果有多个window.onload方法,只会执行一个
$(document).ready()可以同时编写多个,并且都可以得到执行
3.简化写法
window.onload没有简化写法
$(document).ready(function(){})可以简写成$(function(){});
1.先对代码进行预处理(编译),然后再执行。预处理会跳过执行语句,只处理声明语句,同样也是按从上到下按顺序进行的。包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。 即使声明是在调用的下方进行的,但浏览器仍然先声明再调用(执行),这个现象叫做“提升”。所以,即便一个函数的声明在下方,在前面仍然可以正常执行这个函数。
例如 var a = 1,在预处理阶段会把这句话拆成两句:
var a;
a = 1;
2.完成预处理之后,JavaScript代码会从上到下按顺序执行逻辑操作和函数的调用。
var a=1;
function func(){
console.log(a);
var a=2;
console.log(a);
}
func();
js作用域链变量访问规则
(1)、当前作用域内存在要访问的变量时,则使用当前作用域中的变量。
(2)、当前作用域中不存在要访问的变量时,则会到上一层作用域中寻找,直到全局作用域。
js主要用来操控和重新调整DOM,通过修改DOM结构,从而来达到修改页面效果的目的
▲JSON数据是一种按照js对象语法的数据格式
▲对象
对象是一个包含相关数据和方法的集合(通常由一些变量和函数组成,我们称为对象里面的属性和方法)
点表示法person.interests[1]
括号表示法person['name']['first']
括号表示法一个有用的地方是它不仅可以动态的去设置对象成员的值,还可以动态的去设置成员的名字。
function Person(name) {
this.name = name;
this.greeting = function() {
alert('Hi! I\'m ' + this.name + '.');
};
}
var person1 = new Person('Bob');
var person2 = new Person('Sarah');
{
name : 'Bob',
greeting : function() {
alert('Hi! I\'m ' + this.name + '.');
}
}
{
name : 'Sarah',
greeting : function() {
alert('Hi! I\'m ' + this.name + '.');
}
}
var person2 = Object.create(person1);
var person1 = new Object({
name : 'Chris',
age : 38,
greeting : function() {
alert('Hi! I\'m ' + this.name + '.');
}
});
JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象用于一个原型对象,对象以其原型为模板,从原型继承方法和属性。原型对象也可能拥有原型,并从中继承方法和属性,一层一层以此类推,这种关系被称为原型链,准确的说,这些属性和方法定义在Object的构造器函数(construcor function)之上的prototype属性上,而非对象实例本身
js对象实例和他的构造器之间建立一个链接(它就是__proto__属性,他是从构造函数的prototype属性派生的)
Object.getPrototypeOf(obj)和obj.__proto__一样
每个函数都有一个特殊的属性叫做原型(prototype)
js中到处都是通过原型链继承的例子,比如,你可以尝试从Sting,Date,Number和Array全局对象的原型中寻找方法和属性,它们都在原型上定义了一些方法,因此你创建一个字符串时
var myString = 'This is my string.';
myString 立即具有了一些有用的方法,如 split()、indexOf()、replace() 等。
constructor属性
每个实例对象都从原型中继承一个constructor属性,该属性指向了用于构造此实例对象的构造函数
function m (first, last, age) {
this.first = first
this.last = last
this.age = age
}
var person1 = new Person('Bob', 'Smith', 32)
var person2 = Object.create(person1)
console.log(person2.constructor == person1.constructor);
function Person(first, last, age, gender, interests) {
this.name = {
first,
last
};
this.age = age;
this.gender = gender;
this.interests = interests;
};
Person.prototype.greeting = function() {
alert('Hi! I\'m ' + this.name.first + '.');
};
function Teacher(first, last, age, gender, interests, subject) {
Person.call(this, first, last, age, gender, interests);
this.subject = subject;
}
.call()新指定您调用的函数里所有“this”指向的对象
对象方法
Object.keys()此方法可以获取对象所有可枚举的属性
var obj = {
name: "李白",
age: 24
}
▲XML
window.onload=function(){
var b=document.getElementsByTagName('input')[0]
b.onclick=function(){
var url='server.php'
var xhr=createXHR()
xhr.open('post',url,true)
xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200||xhr.status==0){
console.log(xhr.responseText
}
}
}
xhr.send('callbakc=functionName')
}
}
var xhr = new XMLHttpRequest();
xhr.responseType = "json";
xhr.onreadystatechange = function (){
if(xhr.readyState == 4 && xhr.status == 200){
console.log(xhr.response);
}
}
xhr.open("POST", "http://bufantec.com/api/test/user/doLogin");
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
xhr.send("username=libai&password=123456");
请求一般分成 4 个步骤。
var xhr=new XMLHttpRequest()
xhr.open(method,url,async,user,password)
xhr.send(null);
0 UNSENT 代理被创建,但尚未调用 open() 方法。
1 OPENED open() 方法已经被调用。
2 HEADERS_RECEIVED send() 方法已经被调用,并且头部和状态已经可获得。
3 LOADING 解析中; responseText 属性已经包含部分数据。
4 DONE 解析完成。
var xhr = new XMLHttpRequest();
console.log('UNSENT', xhr.status);
xhr.open('GET', '/server', true);
console.log('OPENED', xhr.status);
xhr.onprogress = function () {
console.log('LOADING', xhr.status);
};
xhr.onload = function () {
console.log('DONE', xhr.status);
};
xhr.send(null);
xhr.getResponseHeader("Content-Type")
xhr.setResponseHeader('Content-Type','application/x-www-form-urlencoded')
▲js高阶函数
高阶函数:对其他函数进行操作的函数,函数作为参数,函数作为返回值
this指向
定时器this 指向window
function Product(name,price){
this.name=name;
thsi.price=price;
}
function Food(name,price){
Product.call(this,name,price)
this.category='food'
}
call()方法接受的是一个参数列表,而apply()方法接受的是一个包含多个参数的数组
闭包closure有权访问另一个函数作用域中的变量的函数,延伸了变量的作用范围
▲数据类型
js中的变量都是保存到栈内存的,基本数据类型的值在栈内存中存储,值与值之间是独立存在的,修改一个变量不会影响其他的变量
Undefined是没有定义的(在使用var声明变量但未对其初始化,这个变量即是undefined),
null是定义了但是是空,null表示一个空对象指针 typeof操作符检测null值返回Object
string类型 字符创是不可变得,一旦创建,值就不能改变
object类型
constructor保存着用于创建当前的函数
hasOwnProperty(propertyName)检查当前属性在当前对象实例中是否存在,propertyName必须是字符串形式指定
例如:o.hasOwnProperty(“name”)
Symbol 类型
Symbol 类型的对象永远不相等,因此,可以用解决属性名冲突的问题(适用于多少编码
判断数据类型
typeof
toString
toLocaleString
检测数据类型方法:
instanceof操作符
对象的constructor属性
Array.isArray检验是否为数组
var obj=new Object()
obj.name='swk'
var obj2=obj
obj.name='zbj'
obj2.name='zbj'
obj2=null
console.log(obj2==obj);
var a = 10
var b = 10
console.log(a == b);
var obj3 = new Object()
var obj4 = new Object()
obj3.name = '1'
obj4.name = '1'
console.log(obj3 == obj4);
▲判断数据类型的方法
console.log(typeof 1);
console.log(typeof 'abc');
console.log(typeof true);
console.log(typeof undefined);
console.log(typeof null);
console.log(typeof function fn() { });
console.log(typeof [1, true]);
console.log(typeof {w actions: 1 });
console.log(10 instanceof Number);
console.log('10' instanceof String);
console.log(false instanceof Boolean);
console.log(null instanceof Object);
console.log([1, 2, 3] instanceof Array);
console.log(function fn() { } instanceof Function);
console.log({ a: 1, c: 2 } instanceof Object);
console.log(new Number() instanceof Number);
console.log(new String() instanceof String);
let num = 12
console.log(num.constructor == Number);
console.log('abc'.constructor == String);
function Fn() {}
let dog = new Fn()
console.log(dog.constructor == Fn);
let abc = [1, 2]
console.log(Object.prototype.toString.call(abc));
let abc = 1
console.log(Object.prototype.toString.call(abc));
let abc = 'abc'
console.log(Object.prototype.toString.call(abc));
let abc = function(){}
console.log(Object.prototype.toString.call(abc));
let abc = {a:1}
console.log(Object.prototype.toString.call(abc));
var arr = [1, 2, 3];
console.log(toString.call(arr));
console.log(arr.toString());
▲克隆
【简单来说:就是类似给变量起了一个新的名字,但实际上还是原来的】。
注:一般情况下:简单类型赋值是 传值 !!, 复杂类型赋值是 传址!!。
当对某个数据(数组或对象)进行拷贝后,修改新数据(拷贝后的数据)里面第1层的数据是不会影响老数据(被拷贝的数据)的,但是如果还要第2层 或 更深层次的数据(复杂数据类型),它仍然是有关联的,如果修改了新数据,那么老数据也会被修改。
浅拷贝一般意义不大,了解就行,这里就不贴代码了。根据上面浅拷贝的问题,此时:深拷贝就排上用场了。
* 就是在拷贝数据(数组或对象)时,不管数据里面有多少层,是简单 还是 复杂数据类型,只要进行深拷贝后,和老数据(之前被拷贝的数据)就毫无关联,相互独立,互不影响!在修改新数据,对老数据毫无影响。
* 作用:打断两个对象或数组之间的引用关系!
* 原理:在对数组或对象进行拷贝,使用递归循环复制,而每次递归都是开辟一个新的内存地址(指针),所以一般只要不是同一个内存地址,就不会修改其值
简单来讲:当拷贝一个数据后,和原来的数据就没有任何联系了,因为它们不是同一个指针。
无论是浅拷贝还是深拷贝,一般都用于操作Object 或 Array之类的复合类型。
比如想对某个数组 或 对象的值进行修改,但是又要保留原来数组 或 对象的值不被修改,此时就可以用深拷贝来创建一个新的数组 或 对象,从而达到操作(修改)新的数组 或 对象时,保留原来数组 或 对象。
如数组方法:concat(),filter(),slice(),map()等。它们在修改数组时,不会修改原来的数组,而是返回一个新的数组。
var obj = { a: 1, b: 2 }
var obj2=Object.assign({},obj)
console.log(obj2);
console.log(obj2==obj);
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(returnedTarget)
console.log(target == returnedTarget);
console.log(source);
var oo = { a: 1, b: 2 }
var oo2 = { ...oo }
oo2.c = 3
console.log(oo2);
console.log(oo);
console.log(oo==oo2);
var cc = [{
name: '臧三',
childs: ['小明', '小芳']
}]
var cc2=JSON.parse(JSON.stringigy(cc))
console.log(cc==cc2);
▲异步
状态:pending(初始化)=>fulfilled(操作成功)/rejected(操作失败)
var promise=new Promise(传一个函数)
function f3() {
return new Promise((res, rej) => {
res('abc')
})
}
async function f5() {
console.log(1);
var c = await f3();
console.log(c);
}
f5()
function f4() {
return Promise.reject('cuowu')
}
async function f6() {
try {
var d = await f4()
console.log(d);
} catch (e) {
console.log(e);
}
}
f6()
let p1 = new Promise((res, rej) => {
res('成功了')
})
let p2 = new Promise((res, rej) => {
rej('失败了')
})
let p3 = new Promise((res, rej) => {
rej('shibai')
})
Promise.all([p1, p2, p3]).then((result) => {
console.log(result);
}).catch((err) => {
console.log(err);
})
Promise.race([p1, p2, p3]).then((result) => {
console.log(result);
}).catch((err) => {
console.log(err);
})
获取时间
var date=new Date()
date.getHours()
throw语句 try{}catch{}语句
<p>请输入 5 和 10 之间的一个数:</p>
<input id="demo" type="text"><button type="button" onclick="myFunction()">检测输入</button>
<p id="message"></p>
function myFunction() {
var message, x;
message = document.getElementById("message");
message.innerHTML = "";
x = document.getElementById("demo").value;
try {
if(x == "") throw "为空";
if(isNaN(x)) throw "不是一个数字";
if(x > 10) throw "太大了";
if(x < 5) throw "太小了";
}
catch(err){
message.innerHTML = "输入的值 " + err;
}
}
。
|