『笔记』『教程』自制随机显示必应每日一图，以及API代码及调用方法
前言主题有好多模板设置了分类的背景图，调用了第三方api但是最近第三方挂了这就是图省事不写代码的后果，一旦图片都失效，网站打开速度慢不说，图片的背景图还是灰蒙蒙一片，非常尴尬。。。百度了下必应每日api源代码有很多，但是随机显示的也都是调用人家自己的，这样就可能再次出现无法打开的情况，但是仅仅调用一张图片又略显单调（最烦我这种啥也不是，要求还多的人。。。）终于皇天不负有心人让我找到了一个随机显示必应图片的api调用方法，附上代码及适用教程。调用方法(教程和代码在下方)此API只支持https调用，所有参数均仅适用于以 GET 方式进行请求，可直接插入img标签中请求地址：（不要适用本站api代码，跨域）https://www.hellolin.cn/api-hello/bing调用参数参数代码参数含义可用参数rand是否随机显示最近8天内的图片true or falseday显示指定的最近图片-1，0，1，2，3，4，5，6，7(0为今天，-1为昨天)size指定获取图片大小详见下方可用分辨率info获取图片基础信息（json格式）true or false以上所有参数均非必要，默认参数为rand=false，day=0，size=1920×1080，info=false可用分辨率1920x10801366x7681280x7681024x768800x600调用示例默认调用：https://www.hellolin.cn/api-hello/bing不带任何参数调用，显示必应当天图片。Info调用：https://www.hellolin.cn/api-hello/bing?info=true返回值：{ title:Micheldever Wood的蓝铃花，英国汉普郡 (© Hursley/Getty Images Plus), url:https://www.bing.com/th?id=OHR.BluebellWood_ZH-CN8128422960_1920x1080.jpg, link:https://www.bing.com/search?q=%E8%93%9D%E9%93%83%E8%8A%B1&form=hpcapt&mkt=zh-cn, time:20200419 }随机调用:(随机显示一张图片)https://www.hellolin.cn/api-hello/bing?rand=true {mtitle title="随机显示，刷新更换"/}教程和API代码{hide}首先在网站根目录新建一个php文件，例如：index.php，然后粘贴如下代码：<?php //判断是否随机调用 if ($_GET['rand']==='true') { $gettime = rand(-1,7); }else{ //若不为随机调用则判断是否指定日期 $gettimebase = $_GET['day']; if (empty($gettimebase)) { $gettime = 0; }else{ $gettime = $gettimebase; } } //获取Bing Json信息 $json_string = file_get_contents('https://www.bing.com/HPImageArchive.aspx?format=js&idx='.$gettime.'&n=1'); //转换为PHP数组 $data = json_decode($json_string); //提取基础url $imgurlbase = "https://www.bing.com".$data->{"images"}[0]->{"urlbase"}; //判断是否指定图片大小 $imgsizebase = $_GET['size']; if (empty($imgsizebase)){ $imgsize = "1920x1080"; }else{ $imgsize = $imgsizebase; } //建立完整url $imgurl = $imgurlbase."_".$imgsize.".jpg"; //获取其他信息 $imgtime = $data->{"images"}[0]->{"startdate"}; $imgtitle = $data->{"images"}[0]->{"copyright"}; $imglink = $data->{"images"}[0]->{"copyrightlink"}; //判断是否只获取图片信息 if ($_GET['info']==='true') { echo "{title:".$imgtitle.",url:".$imgurl.",link:".$imglink.",time:".$imgtime."}"; }else{ //若不是则跳转url header("Location: $imgurl"); }{/hide}结语保存文件，最后打开网页查看效果，如果有不同需求网址后面加“?参数代码=true(或者false)”，参考上面的参数表格完整代码就是（以随机为例）： https://网址/index.php?rand=true 酱婶儿的就OK啦，把这个链接放在主题模板的背景图接口就大功告成！
『原创』『教程』给自己博客的侧栏增加社交信息，方便业务（PY）联系
前言前不久突发奇想，录了一个视频然后留了自己的博客，却发现博客却没有链接回去的方式，所以就写了一个社交信息的侧栏模块然后有小伙伴看到了，专门留言让我出个教程，当时答应的好好的，可是一连鸽了好几天，今天进入留言板看到许诺的话，不禁老脸一红，差点忘了这茬了 ::(狂汗) 成果展示博客的侧栏增加社交信息2.0 这个模块适合任何主题及程序，只需要根据自己的主题或者程序进行改进就行我这里演示的是我正在使用的Joe主题，是一款轻量、开源的主题{tabs}{tabs-pane label="PC展示"}{/tabs-pane}{tabs-pane label="PE展示"}{/tabs-pane}{/tabs}教程开始一、添加PC端打开 Joe/public/aside.php 文件，然后在想要增加的位置添加以下代码{tabs}{tabs-pane label="代码"}{hide} <?php if ($this->options->SocialInfo && (($this->options->SocialSwitch === 'on') || ($this->options->SocialSwitch === 'on2'))) : ?> <?php $SocialInfo = $this->options->SocialInfo; if ($SocialInfo) { $SocialInfo_arr = explode("\r\n", $SocialInfo); if (count($SocialInfo_arr) > 0) { for ($i = 0; $i < count($SocialInfo_arr); $i++) { $QQ = explode("||", $SocialInfo_arr[$i])[0]; $WeChat = explode("||", $SocialInfo_arr[$i])[1]; $BiliBili = explode("||", $SocialInfo_arr[$i])[2]; $Weibo = explode("||", $SocialInfo_arr[$i])[3]; } } } ?> <a href="https://wpa.qq.com/msgrd?v=3&uin=<?php echo trim($QQ) ?>&site=qq&menu=yes" target="_blank" title="QQ"> <img src="<?php echo trim($WeChat) ?>" /> <a href="https://space.bilibili.com/<?php echo trim($BiliBili) ?>" target="_blank" title="哔哩哔哩"> <a href="https://weibo.com/u/<?php echo trim($Weibo) ?>" target="_blank" title="微博"> <?php endif; ?>{/hide}{/tabs-pane}{tabs-pane label="位置"}{/tabs-pane}{/tabs}二、添加PE端打开 Joe/public/header.php 文件，然后在想要增加的位置添加上面PC的代码PE端的代码和上面的一样，只需要将 换成 三、添加后台直接在 Joe/functions.php 添加以下代码（当然，如果看过我之前的文章，也可以放在 Joe/public/custom.php 里面）// 侧栏社交信息开关 $SocialSwitch = new Typecho_Widget_Helper_Form_Element_Select( 'SocialSwitch', array( 'off' => '关闭（默认）', 'on' => '开启PC社交信息', 'on1' => '开启PE社交信息', 'on2' => '同时开启PC与PE社交信息', ), 'off', '是否启用侧栏社交信息', '介绍：开启后，侧栏展示社交信息功能（必须填写下面的侧栏社交信息）' ); $SocialSwitch->setAttribute('class', 'joe_content joe_custom'); //没有custom.php就把joe_custom改成joe_other $form->addInput($SocialSwitch->multiMode()); //侧栏社交信息 $SocialInfo = new Typecho_Widget_Helper_Form_Element_Textarea( 'SocialInfo', NULL, NULL, '侧栏社交信息', '介绍：用于设置侧栏社交信息 格式：你的QQ号 || 你的微信二维码链接 || 你的B站ID || 你的微博ID 例如：123456 || https://www.a.con/a.png || 13503064 || 3125196513 ' ); $SocialInfo->setAttribute('class', 'joe_content joe_custom'); //没有custom.php就把joe_custom改成joe_other $form->addInput($SocialInfo);然后你网站后台主题就会出现这样两项，根据相应的格式把你的信息填进去就行了四、添加显示样式在 Joe/assets/css/joe.global.min.css 里添加以下样式我这里的样式是已经压缩了的，如果想要自己修改，只需要在代码编辑器里格式化以下就行了.top-social{position:relative;padding:10px 0;width:250px;display:flex;flex-wrap:wrap;background:var(--background);justify-content:space-around;margin-bottom:15px;border-radius:var(--radius-wrap);box-shadow:var(--box-shadow)}.top-social li{width:50px;text-align:center;padding:5px 0px}.top-social li img{height:25px}.top-social .wechat{position:relative}.top-social .wechat .wechatInner{display:none;position:absolute;box-shadow:0px 1px 4px 2px var(--theme);border-radius:var(--radius-wrap);transition:.7s all ease;background:var(--background);-webkit-transition:.7s all ease;top:-175px;left:-45px;transform:translate3d(0, 16px, 0);width:140px;height:140px}.top-social .wechat .wechatInner::before{content:"";position:absolute;bottom:-16px;left:0;right:0;margin:auto;display:inline-block;width:0px;border:18px solid transparent;border-bottom:none;border-top-color:#fff;filter:drop-shadow(0px 4px 2px var(--theme))}.top-social .wechat .wechatInner img{border-radius:var(--radius-wrap);width:140px;height:auto;padding:0;background:none}.top-social .wechat:hover .wechatInner{display:block}.pe-social{width:100%}结语教程到此就结束了，其实还是很简单的不过我又想把这个模块做成填写ico图片链接和跳转链接的自定义模块，就可以自由添加更多的社交信息但是那样只能舍弃微信那个移入弹窗的效果，所以很难取舍呀{timeline}{timeline-item color="#19be6b"}2022.3.16 在这里挖一个坑吧：利用JS选择对应的元素，实现微信的弹窗效果（令人头秃 :@(哭泣) ）{/timeline-item}{timeline-item color="#ed4014"}2022.3.19 Flag已实现，请移步 侧栏社交信息2.0 {/timeline-item}{/timeline}
数据类型1、分类基本（值）类型{alert type="info"}String：任意字符串Number：任意的数字Boolean：true/falseundefined：undefinednull ：null{/alert}对象（引用）类型{alert type="info"}object ：任意对象function ：函数，一种特别的对象（可以执行）array ：数组，一种特别的对象（数值具有下标，内部数据是有序的）{/alert}2、类型的判断{alert type="success"}typeof ：可以判断 undefined/ 数值 / 字符串 / 布尔值Boolean / Function -不能判断 null和object object和arrayinstanceof ：判断对象的具体类型=== ：全等，可以判断undefined,null{/alert} 1、undefined与null的区别？undefined 代表定义未赋值null 代表定义并赋值了，但是值为null2、什么时候给变量赋值为null？初始赋值：表明将要赋值为对象结束前：让对象成为垃圾对象（垃圾回收）3、严格区别变量类型与数据类型？（1）数据的类型基本类型对象类型（2）变量的类型（变量内存值的类型）基本类型：保存的基本类型的数据引用类型：保存的是地址值对象类型即是引用类型 数据、变量、内存定义1、什么是数据存储在内存中代表特点信息的东西，本质上是0101.......数据的特点：可传递、可运算2、什么是内存内存条通电以后产生的可存储数据的空间（临时的）内存产生和死亡： 内存条（电路板）==>通电==>产生内存空间==>存储数据==>处理数据==>断电==>内存空间和数据都消失一块小内存的2个数据 `内部存储的数据` `地址值`内存分类 `栈：保存全局变量/局部变量（变量名）` `堆：对象（函数、数组）` 3、什么是变量可变化的量：由变量名、变量值组成每个变量都对应一块小内存，变量名用来查找对应的内存，变量值就是内存中保存的数据4、内存、数据、变量三者之间的关系内存是用来存储数据的空间变量是内存的标识
DOM（文本对象模型）（20）鼠标拖拽的事件拖拽(一、二) 我是一段文字 box的偏移量=鼠标的偏移量-元素的偏移量捕获测试 按钮01 按钮02 拖拽（三） 我是一段文字 <img src="https://cdn.jsdelivr.net/gh/aill66/cdn@latest/usr/uploads/2021/08/809131067.png" id="img1" style="width:100px; position:absolute;" （21）滚轮的事件 （22）键盘的事件 键盘移动vid {nextPage/}BOM（浏览器对象模型）BOM可以通过JS来操作浏览器在BOM中提供了一组对象，用来完成对浏览器的操作BOM对象{alert type="success"}Window 代表的是整个浏览器的窗口，同时也是网页中的全局对象Navigator 代表当前浏览器的信息，通过该对象可以识别不同的浏览器Location 代表当前浏览器的地址栏信息，通过location可以获取地址栏信息或者操作浏览器跳转页面History 代表浏览器的历史记录，可以通过该对象来操作浏览器的历史记录由于隐私原因，该对象不能获取到具体的历史记录，只能操作浏览器向前或向后翻页，而且该操作只在当次访问有效Screen 代表用户的屏幕信息，通过该对象可以获取到用户的显示器的相关信息这些BOM对象在浏览器中都是作为window对象的属性保存的{/alert}// console.log(window.navigator); console.log(navigator); console.log(location); console.log(history);一、Navigator（浏览器信息）代表当前浏览器的信息，通过该对象可以识别不同的浏览器由于历史原因（网景公司倒闭了），Navigator对象中的大部分属性都已经不能识别浏览器了一般只会使用userAgent来判断浏览器的信息userAgent是一个字符串，这个字符串包含有用来描述浏览器信息的内容，不同的浏览器会有不同的userAgent// appCodeName 返回浏览器名称的代码 // appName 返回浏览器的名称 // userAgent 返回一个字符串来描述浏览器的信息 // alert(navigator.appName); // 在IE11中已经将微软和IE相关的标识都去除了，所以基本不能通过userAgent来识别浏览器是不是IE了 var ua = navigator.userAgent; console.log(ua); if(/firefox/i.test(ua)){ alert("我是火狐"); }else if(/chrome/i.test(ua)){ alert("我是Chrome"); }else if(/msie/i.test(ua)){ alert("我是IE浏览器"); }else if("ActiveXObject" in window){ alert("你是IE11，我已经抓住你了"); } // 如果不能通过userAgent来判断浏览器信息，还可以通过一些浏览器中特有的对象来判断浏览器的信息 // 比如：ActiveXObject // alert("ActiveXObject" in window); if("ActiveXObject" in window){ alert("你是IE，我已经抓住你了"); }else{ alert("你不是IE"); } 二、History（历史记录）代表浏览器的历史记录，可以通过该对象来操作浏览器向前或向后翻页 点我一下 History 去下一个页面 三、Location（浏览器地址栏）该对象中封装了浏览器的地址栏的信息 点我一下 四、Window（浏览器的窗口）window的方法1、 定时调用 （1）切换图片练习 开始 停止 （2）修改div移动练习 2、 延时调用 （1）定时器的应用一 点击按钮以后box1向右移动 {nextPage/}（2）定时器的应用二 点击按钮以后box1向右移动 点击按钮以后box1向左移动 （3）定时器的应用三 点击按钮以后box1向右移动 点击按钮以后box1向左移动 点击按钮以后box2向右移动 测试按钮 tools.js（用于存放工具程序） // 尝试创建一个可以执行简单动画的函数 // 参数:obj:要执行动画的对象 // attr:要执行动画的样式，比如left height top // target:执行动画的目标位置 // speed:移动的速度（正数向右移动，负数向左移动） // callback:回调函数，将会在动画执行完毕以后执行 function move(obj,attr,target,speed,callback){ // 关闭上一个定时器 clearInterval(obj.timer); // 获取box1目前的位置 var current = parseInt(getStyle(obj,attr)); // 判断速度speed的正负值 // 如果从0向800移动则speed为正，如果从800向0移动则speed为负 if(current > target){ // 此时速度应为负值 speed = -speed; } // 开启一个定时器用来执行动画效果 // 向执行动画的对象中添加一个timer属性，用来保存它自己的定时器的标识 obj.timer = setInterval(function(){ // 获取box1原来的left值 var oldValue = parseInt(getStyle(obj,attr)); // 在旧值的基础上增加,给box添加移动速度 var newValue = oldValue + speed; // 向左移动时需要判断newValue是否小于target // 向右移动时需要判断newValue是否大于于target if((speed < 0 && newValue < target) || (speed > 0 && newValue > target)){ newValue = target; } // 将新值设置给obj obj.style[attr] = newValue + "px"; // 当box1移动到了0px时，使其停止执行动画 if(newValue == target){ // 达到目标关闭定时器 clearInterval(obj.timer); // 动画执行完毕，调用回调函数 callback && callback(); } },30); }; /* 定义一个函数，用来获取指定元素的当前的样式 * 参数： * obj 要获取样式的元素 * name 要获取的样式名*/ function getStyle(obj,name){ if(window.getComputedStyle){ //正常浏览器的方式，具有getComputedStyle()方法 return getComputedStyle(obj,null)[name]; }else{ //IE8的方式，没有getComputedStyle()方法 return obj.currentStyle[name]; } };{nextPage/}3、 轮播图的改进 {nextPage/}4、类的操作 点击按钮修改box的样式 tools.js（工具函数）// 尝试创建一个可以执行简单动画的函数 // 参数:obj:要执行动画的对象 // attr:要执行动画的样式，比如left height top // target:执行动画的目标位置 // speed:移动的速度（正数向右移动，负数向左移动） // callback:回调函数，将会在动画执行完毕以后执行 function move(obj, attr, target, speed, callback) { // 关闭上一个定时器 clearInterval(obj.timer); // 获取box1目前的位置 var current = parseInt(getStyle(obj, attr)); // 判断速度speed的正负值 // 如果从0向800移动则speed为正，如果从800向0移动则speed为负 if (current > target) { // 此时速度应为负值 speed = -speed; } // 开启一个定时器用来执行动画效果 // 向执行动画的对象中添加一个timer属性，用来保存它自己的定时器的标识 obj.timer = setInterval(function () { // 获取box1原来的left值 var oldValue = parseInt(getStyle(obj, attr)); // 在旧值的基础上增加,给box添加移动速度 var newValue = oldValue + speed; // 向左移动时需要判断newValue是否小于target // 向右移动时需要判断newValue是否大于于target if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) { newValue = target; } // 将新值设置给obj obj.style[attr] = newValue + "px"; // 当box1移动到了0px时，使其停止执行动画 if (newValue == target) { // 达到目标关闭定时器 clearInterval(obj.timer); // 动画执行完毕，调用回调函数 callback && callback(); } }, 30); }; /* 定义一个函数，用来获取指定元素的当前的样式 * 参数： * obj 要获取样式的元素 * name 要获取的样式名*/ function getStyle(obj, name) { if (window.getComputedStyle) { //正常浏览器的方式，具有getComputedStyle()方法 return getComputedStyle(obj, null)[name]; } else { //IE8的方式，没有getComputedStyle()方法 return obj.currentStyle[name]; } }; // 定义一个函数来向一个元素添加指定的class属性值 /*参数： obj 要添加class属性的元素 cn 要添加的class值*/ function addClass(obj, cn) { // 检查obj中是否含有cn if (!hasClass(obj, cn)) { // 如果没有cn则添加cn（添加一个空格防止直接拼串） obj.className += " " + cn; } }; // 判断一个元素中是否含有指定的class属性值 /*参数 obj 要添加class属性的元素 cn 要添加的class值 如果有该class值则返回true，否则返回false*/ function hasClass(obj, cn) { // 判断obj中是否有cn这个class值 // 创建一个正则表达式 // var reg = /\bb2\b/; var reg = new RegExp("\\b" + cn + "\\b"); return reg.test(obj.className); }; // 删除一个元素中指定的class属性 function removeClass(obj, cn) { // 创建一个正则表达式 var reg = new RegExp("\\b" + cn + "\\b"); // 删除class obj.className = obj.className.replace(reg, ""); }; // toggleClass用来切换一个类 // 如果元素中有指定类则删除，没有则添加 function toggleClass(obj, cn) { // 判断obj中是否含有cn if (hasClass(obj, cn)) { // 有则删除 removeClass(obj, cn); } else { // 没有则添加 addClass(obj, cn); } };5、二级菜单完善 二级菜单 在线工具 图像优化 收藏夹图标生成器 邮件 梯度图像 按钮生成器 支持我们 图像优化 收藏夹图标生成器 邮件 梯度图像 按钮生成器 合作伙伴 图像优化 邮件 梯度图像 按钮生成器 支持我们 图像优化 邮件 梯度图像 按钮生成器 二级菜单动画过渡 二级菜单 在线工具 图像优化 收藏夹图标生成器 邮件 梯度图像 按钮生成器 支持我们 图像优化 收藏夹图标生成器 邮件 梯度图像 按钮生成器 合作伙伴 图像优化 邮件 梯度图像 按钮生成器 支持我们 图像优化 邮件 梯度图像 按钮生成器 五、JSON JSON的兼容性
对象JS中的数据类型{alert type="success"}String 字符串Number 数值Boolean 布尔值Null 空值Undefined 未定义以上五种类型属于基本类型，只要不是以上五种，都是对象Object 对象{/alert}基本数据类型都是单一的值，值和值之间没有任何联系在JS中用来表示一个人的信息（name gender age）var name="张三"; var gender="男"; var age="18";如果使用基本数据类型，创建的变量都是独立的，不能成为一个整体对象属于一种复合的数据，在对象中可以保存多个不同数据类型的属性一、对象的分类1、内建对象{alert type="success"}由ES标准中定义的对象，在任何的ES的实现中都可以使用比如：Math String Number Boolean Function Object……{/alert}2、宿主对象{alert type="success"}由JS的运行环境提供的对象，主要由浏览器提供的对象比如：BOM(浏览器对象模型) DOM(文档对象模型){/alert}console.log(); document.write(); //都是由浏览器提供3、自定义对象{alert type="success"}由开发人员自己创建的对象{/alert}二、创建对象1、 使用 new 关键字调用的函数，是构造函数constructor2、 构造函数是专门用来创建对象的函数3、 使用typeof来检查一个对象时，会返回object{alert type="warning"}在对象中保存的值称为属性向对象添加属性，语法： 对象.属性名=属性值; {/alert}var obj = new Object(); //console.log(typeof obj); //向obj添加一个name属性 obj.name="张三"; //向obj添加一个gender属性 obj.gender="男"; //向obj添加一个age属性 obj.age="18"; console.log(obj);{alert type="warning"}读取对象中的属性语法： 对象.属性名; 如果读取对象中没有的值，不会报错而是会返回undefined{/alert}var obj = new Object(); //向obj添加一个name属性 obj.name="张三"; //向obj添加一个gender属性 obj.gender="男"; //向obj添加一个age属性 obj.age="18"; console.log(obj.name);//输出“张三”{alert type="warning"}修改对象中的属性语法： 对象.属性名 = 新值; {/alert}var obj = new Object(); //向obj添加一个name属性 obj.name="张三"; //向obj添加一个gender属性 obj.gender="男"; //向obj添加一个age属性 obj.age="18"; //修改obj的name属性值 obj.name="孙悟空" console.log(obj.name);//输出“孙悟空”{alert type="warning"}删除对象中的属性语法： delete 对象.属性名; {/alert}var obj = new Object(); //向obj添加一个name属性 obj.name="张三"; //向obj添加一个gender属性 obj.gender="男"; //向obj添加一个age属性 obj.age="18"; //删除obj的name属性值 delete obj.name; console.log(obj.name);//没有该值，输出undefined三、属性名和属性值1、属性名对象的属性名不强制要求遵守标识符的规范尽量按照标识符的规范设置{alert type="success"}如果使用特殊的属性名，不能采用.的方式来操作需要使用另一种方式，语法： 对象["属性名"]=属性值;读取时也需要采用这种方式使用[]这种形式去操作属性更加灵活在[]中可以直接传递一个变量，这样变量值是多少就会读取那个属性{/alert}var obj = new Object(); obj["123"]=567; obj["nihao"]="你好"; var n = "nihao" console.log(obj["123"]); console.log(obj[n]); 2、属性值JS对象的属性值，可以是任意的数据类型， 甚至也可以是一个对象 {alert type="warning"}in 运算符通过该运算符可以检查一个对象中是否含有制定的属性，有返回true，没有则返回false语法："属性名" in 对象{/alert}var obj = new Object(); obj.name="孙悟空"; obj.test= true; obj.test= null; obj.test= undefined; var obj2 = new Object(); obj2.name="猪八戒"; obj.test=obj2; console.log(obj.test);//返回 name=“猪八戒” console.log(obj.test.name);//返回 “猪八戒” console.log("name" in obj);//返回true四、基本、引用数据类型（一）基本数据类型String Number Boolean null Undefined{alert type="success"}JS中的变量都是保存在栈内存的基本数据类型的值直接在栈内存中存储值与值之间是独立存在的，修改一个变量不会影响其他变量{/alert}var a = 123; var b = a; a++; console.log("a"= +a); //输出为124 console.log("b"= +b); //输出为123（二）引用数据类型对象：Object{alert type="success"}JS中的变量都是保存在栈内存的对象是保存到堆内存中的，每创建一个新的对象，就会在堆内存中开辟一个新的空间而变量保存的是对象的内存地址（对象的引用），如果两个变量保存的是同一个对象引用当通过一个变量修改属性时，另一个也会受到影响{/alert}var obj = new Object(); obj.name = "孙悟空"; var obj2 = obj; console.log(obj.name);//输出 孙悟空 console.log(obj2.name);//输出 孙悟空 //修改obj的name属性 obj.name = "猪八戒"; console.log(obj.name);//输出 猪八戒 console.log(obj2.name);//输出 猪八戒 obj2 = null; console.log(obj);//输出 Object console.log(obj2);//输出 null{alert type="success"}当比较两个基本数据类型的值时，就是比较他们的值当比较两个引用数据类型时，是比较对象的内存地址 如果两个对象一模一样，但是地址不同，它也会返回false{/alert}var a = 10; var b = 10; console.log(a == b); // 返回true var obj3 = new Object(); var obj4 = new Object(); obj3.name = "沙和尚"; obj4.name = "沙和尚"; console.log(obj3 == obj4); // 返回false五、对象字面量使用对象字面量，可以在创建对象时，直接指定对象的属性语法： {属性名:属性值,属性名:属性值....} {alert type="success"}对象字面量的属性名可以加引号也可以不加， 建议不加如果要使用一些特殊的名字，则必须加引号属性名和属性值是一组一组的名值对结构名和值之间使用冒号 : 连接多对名值之间使用逗号 , 隔开如果一个属性之后没有其他属性时， 就不要写逗号 , 了 {/alert}//创建一个对象 //var obj = new Object(); //使用对象字面量来创建一个对象 var obj = {}; obj.name = "孙悟空"; var obj2 = { name:"猪八戒", age:28, gender:"男" test:{ name:"沙和尚", age:27 } }; console.log(obj2.test);//输出name:沙和尚 age:27函数一、函数的简介函数（function）：也是一个对象{alert type="warning"}普通对象只能封装属性函数对象可以封装一些功能（代码），在需要时可以执行这些功能函数可以保存一些代码在需要时调用使用typeof检查一个函数时会返回function{/alert}1、使用构造函数的方式来创建函数{alert type="success"}可以将要封装的代码以字符串的形式传递给构造函数封装到函数中的代码不会立即执行函数中的代码会在函数调用的时候执行调用函数，语法： 函数对象() 当调用函数时，函数中封装的代码会按照顺序执行在实际开发中很少使用构造函数来创建一个函数 {/alert}var fun = new Function( "console.log('这是我的第一个函数');" ); fun.hello = "你好"; console.log(fun.hello);//输出 你好 fun();//输出 这是我的第一个函数2、使用函数声明来创建一个函数语法：中括号可选，可不写function 函数名([形参1，形参2，形参n]){ 语句... }function fun2(){ console.log("这是我的第二个函数"); alert("哈哈哈哈"); document.write("你好"); } fun2();//按顺序输出3个函数3、使用函数表达式来创建一个函数语法：var 函数名 = function([形参1,形参2,形参n]){ 语句... }将一个匿名函数赋值给一个变量var fun3 = function (){ console.log("这是一个匿名函数"); } fun3();二、函数的参数1、形参与实参可以在函数的()中来指定一个或多个形参（形式参数）{alert type="success"}多个形参之间使用 , 隔开，声明形参就相当于在函数内部声明了对应的变量，但是 并不赋值在函数调用时，可以在()中指定实参（实际参数）实参将会赋值给函数中对应的形参调用函数时解析器不会检查实参的类型（可能会存在非法参数）调用函数时解析器也不会检查实参的数量（多余实参不会被赋值）函数的实参可以是任意的数据类型如果实参的数量少于形参的数量，则没有对应实参的形参将会是undefined{/alert}function sum(){ var a = 1; var b = 1; console.log(a+b); } sum(); // 输出 求和值2 //a,b都是形参 function sum (a,b){ cosole.log(a+b+c); } //1,2都是实参，实参可以是任意数据类型 sum(1,2);//输出 求和值3 //3没有对应的形参，将变为undefined sum(1,2,3);//输出 求和值null2、函数的返回值可以使用return来设置函数的返回值语法： return 值{alert type="success"}return后的值将会作为函数的执行结果返回可以定义一个变量来接受该结果在return后的语句不会再执行如果return语句后不跟任何值就相当于返回一个undefined函数中不写return也会返回undefined{/alert}function sum(a,b,c){ // alert(a+b+c); var d = a+b+c; return d; //return; alert("hello"); } //调用函数 // sum(1,2,3) //变量result的值就是函数的执行结果 //函数返回什么result的值就是什么 var result = sum(4,7,8); console.log("result="+result);//输出 求和值193、实参的类型例1： 定义一个函数，判断一个数字是否为偶数，如果是返回true，否则返回falsefunction isOu(num){ if(unm % 2 == 0){ return true; }else{ return false; } //相等于上面的式子 return num % 2 == 0 ; } var result = isOu(2); console.log("result = "+result);//输出true例2： 定义一个函数，可以根据半径计算一个圆的面积，并返回计算结果function mianji(r){ return 3.14*r*r; } var result = mianji(10); console.log("result = "+result);//输出314例3： 创建一个函数，可以在控制台输出一个人的信息实参可以是任意的数据类型，也可以是一个对象当参数过多时，可以将参数封装到一个对象中，然后通过对象传递function sayHello(o){ console.log("我是"+o.name+",今年我"+o.age+"岁了，"+"我是一个"+o.gender+"人，我住在"+o.address); } //创建一个对象 var obj = { name:"孙悟空", age:18, address:"花果山", gender:"男" }; sayHello(obj);例4： 实参可以是一个对象，也可以是一个函数{alert type="warning"}fun(sayHello) 函数对象，相当于直接调用函数对象fun(sayHello()) 调用函数，相当于使用函数的返回值{/alert}function sayHello(o){ console.log("我是"+o.name+",今年我"+o.age+"岁了，"+"我是一个"+o.gender+"人，我住在"+o.address); } //创建一个对象 var obj = { name:"孙悟空", age:18, address:"花果山", gender:"男" }; function fun(a){ console.log("a = "+a);//输出sayHello整个函数 a(obj);//输出sayHello(obj);的结果 } fun(sayHello); fun(sayHello());//输出函数sayHello的返回值4、返回值的类型function fun(){ alert("函数要执行了")； for(var i=0; i<5; i++){ console.log(i); if(i == 2){ break;//break可以退出当前循环 continue;//用于跳过当次循环 return;//可以结束整个函数 } console.log(i); } alert("函数执行完了"); } fun();{alert type="warning"}返回值可以是任意数据可以是对象，也可以是一个函数{/alert}function fun2(){ //var obj = {name:"沙和尚"}; //return obj; return {name:"沙和尚"}; } var a = fun2(); console.log("a="+a.name); function fun3(){ //在函数内部再声明一个函数 function fun4(){ alert("我是fun4"); } //fun4(); return fun4;//fun4函数作为返回值返回 return fun4(); } //a = fun3(); //console.log(a); //a(); fun3()();5、立即执行函数{alert type="warning"}h函数定义完成立即被调用，这种函数叫做立即执行函数立即执行函数一般只会执行一次{/alert}(function(){ alert("我是一个匿名函数"); })(); (function(a,b){ console.log("a = "+a); console.log("b = "+b); })(123,456);6、对象的方法对象的属性值可以是任意数据内心，也可以是一个函数{alert type="warning"}如果一个函数作为一个对象的属性保存，那么这个函数就是这个对象的方法调用这个函数就是调用对象的方法（method）但是它只是名称上的区别，没有其他区别{/alert}var obj = new Object(); obj.name = "孙悟空"; obj.age = 18; obj.sayName function(){ console.log(obj.name); }; function fun(){ console.log(obj.name); } //console.log(obj.sayName); //调用obj的sayName方法 obj.sayName(); //调用函数 fun(); var obj2 = { name:"猪八戒", age:18, sayNme:function(){ console.log(obj2.name); } }; obj2.sayName();7、枚举对象中的属性使用 for...in 语句来枚举对象中的属性语法：for(var 变量 in 对象){ }{alert type="success"}for...in 语句，对象中有几个属性，循环体就会执行几次每次执行时会将对象中的一个属性的名字赋值给变量{/alert}var obj = { name:"孙悟空", age:18, gender:"男", address:"花果山" }; //[]可以传变量 for(var n in obj){ console.log("属性名:"+n); console.log("属性值:"+obj[n]); }三、作用域{alert type="success"}作用域指一个变量的作用的范围在JS中共有两种作用域1、全局作用域2、函数作用域（区域作用域） {/alert}（一）全局作用域{alert type="success"}直接编写在script标签中的Js代码，都在全局作用域全局作用域在页面打开时创建，在页面关闭时销毁在全局作用域中有一个全局对象window（代表的是一个浏览器的窗口，由浏览器创建，可以直接使用）在全局作用域中，创建的变量都会作为window对象的属性保存在全局作用域中，创建的函数都会作为window对象的方法保存全局作用域中的变量都是全局变量，在页面的任意部分都可以访问的到{/alert}function fun(){ var a = 123; } fun(); console.log(a);//报错 var a = 10; var b = 20; var c = "hello"; console.log(window.c);//输出hello function fun(){ console.log("我是fun函数"); } window.fun();//与下面效果相同 fun();1、变量的声明提前{alert type="success"}使用var关键字声明的变量，会在所有的代码执行之前被声明（但是不会赋值）但是如果声明变量时不使用var关键字，则变量不会被声明提前{/alert}var a; console.log("a = "+a); var a = 123;2、函数的声明提前{alert type="success"}使用函数声明形式创建的函数function 函数(){},它会在所有的代码执行之前就被创建， 可以在函数声明前调用函数使用函数表达式创建的函数，不会被声明提前，所有不能在声明前调用{/alert}var fun();//已经赋值 fun();//输出我是fun函数 var fun2;//没有赋值 fun2();//报错，不存在fun2()函数 //函数声明，会被提前创建 function fun(){ console.log("我是fun函数"); } //函数表达式，不会被提前创建 var fun2 = function(){ console.log("我是fun2函数"); }（二）函数作用域（区域作用域）{alert type="success"}调用函数时创建函数作用域，函数执行完毕后函数作用域销毁每调用一次函数，就会创建一个新的函数作用域，他们时=是互相独立的在函数作用域中可以访问到全局作用域的变量，在全局作用域无法访问到函数作用域的变量当在函数作用域操作一个变量时，它会先在自身作用域中寻找，如果有就直接使用，如果没有就向上一级作用域中寻找，直到找到全局作用域，如果全局作用域也没用就会报错在函数中想要访问全局域中的变量可以使用window对象{/alert}var a = 10; function fun(){ var a = "我是函数中的变量a"; var b = 20; //console.log("a = "+a); function fun2(){ console.log("a = "+window.a)； } fun2(); } fun(); console.log("a = "+a);在函数作用域中也有声明提前的特性{alert type="warning"}使用var关键字声明的变量，会在函数中所有代码执行前被声明(不会被赋值)函数声明也会在函数中所有代码执行前被创建在函数中不使用var声明的变量都会变成全局变量定义形参就相当于在函数作用域中声明了变量{/alert}function fun3(){ fun4(); console.log(a); var a = 35; function fun4(){ alert("我是fun4"); } } fun3(); var c = 33; function fun5(){ console.log("c = "+c); var c = 10; //没有var关键字，则会变为全局变量，相当于window.d d = 100; } fun5(); //在全局输出c console.log("d = "+d); //定义形参就相当于在函数作用域中声明了变量 function fun6(e){ alert(e); } fun6();四、debugalert(c); var a = 10; var b = "hello"; c = true; function fun(){ alert("hello"); } var d = 35;使用浏览器F12检查功能进行debug检查
前言学无止境，继续加油！代码块 {alert type="success"}程序是由一条一条语句构成的语句是按照自上而下的顺序一句一句执行的在JS中可以使用 {} 来为语句进行分组同一个 {} 中的语句称为一组语句，也叫代码块 代码块要么都执行，要么都不执行在代码块的后面不需要再编写 ; 结束JS中的代码块只具有分组的作用 ，没有其他用途 代码块内部的内容，在其外部是完全可见{/alert}{ alert("hello"); document.write('class="link"') } { var a = 10; alert("hello"); document.write('class="link"') } console.log("a = "+a)流程控制语句 通过流程控制语句可以控制程序执行流程，使程序可以根据一定的条件来选择执行一、条件判断语句在执行某个语句之前进行判断，成立才会执行语句，不成立则语句不执行 注意：条件判断语句不要使用赋值运算符 = 否则会直接返回true（一）语法一：if语句if(条件表达式){ 语句… }{alert type="success"}if 语句在执行时，会先对条件表达式进行求值判断，如果条件表达式的值为true则执行if后的语句，为false则不会执行if后的语句if语句只能控制紧随其后的那个语句 如果希望if语句可以控制多条语句，可以将这些语句放到一个代码块内代码块不是必须的，但是开发中建议编写,哪怕只有一条语句{/alert}var a = 20; if(a > 10 && a <= 20){ alert("a比10大,并且小于等于20"); }（二）语法二：if…else语句if(条件表达式){ 语句… }else{ 语句… }{alert type="success"}if…else 语句在执行时，会先对条件表达式进行求值判断，如果条件表达式的值为true则执行if后的语句，为false则会执行else后的语句{/alert}var age = 60; if(a >= 60){ alert("你已经退休了"); }else{ alert("你还要继续工作") }（三）语法三：if…else if…else语句if(条件表达式){ 语句… }else if{ 语句… }else if{ 语句… }else{ 语句… }{alert type="success"}if…else if…else 语句执行时，会从上到下依次对条件表达式进行求值判断 如果值为true则执行当前语句，如果值为false则继续向下判断只会有一个代码块被执行，一旦执行语句会直接结束{/alert}var age = 60; if(a > 100){ alert("活着挺没意思"); }else if(a > 60){ alert("你该退休了"); }else if(a > 50){ alert("你还要继续工作"); }else if(a > 17){ alert("你已经成年了"); }else{ alert("你还只是个孩子"); }4、prompt()函数{alert type="warning"}可以在页面弹出一个带有文本框的提示框用户可以在文本框中输入内容，该函数需要一个字符串作为参数prompt()函数的返回值都是字符串string类型{/alert}var score = prompt("参数"); alert(score);（四）实例练习：1、练习一输入0-100的成绩后进行判断并输出相应的结果var score = prompt("请输入成绩"); // 排除小于0大于100的值，同时排除非数字number类型的值 if(score >100 || score < 0 || isNaN(score)) { alert("毙了"); }else{ if(score ==100) { alert("奖励BMW"); }else if(score >= 80){ alert("奖励手机"); }else if(score >= 60){ alert("奖励参考书"); }else{ alert("啥都没有"); } }2、练习二输入三个数据后进行判断并输出相应的结果var height = prompt("请输入身高（cm）"); var money = prompt("请输入财富（万）"); var face = prompt("请输入颜值（px）"); if(height >180 && money > 1000 && face > 500) { alert("一定嫁"); }else if(height >180 || money > 1000 || face > 500) { alert("将就一下"); }}else{ alert("坚决不嫁"); }3、练习三输入三个数据后进行排序并从小到大输出var num1 = +prompt("请输入第一个数"); var num2 = +prompt("请输入第二个数"); var num3 = +prompt("请输入第三个数"); if(num1 < num2 && num1 < num3) { // num1最小，比较num2和num3 if(num2<num3){ alert(num1 + "，" +num2 +" ，"+num3); }else{ alert(num1 + "，" +num3 +" ，"+num2); } }else if(num2 < num1 && num2 < num3) { // num2最小，比较num1和num3 if(num1<num3){ alert(num2 + "，" +num1 +" ，"+num3); }else{ alert(num2 + "，" +num3 +" ，"+num1); } }else{ // num3最小，比较num1和num2 if(num1<num2){ alert(num3 + "，" +num1 +" ，"+num2); }else{ alert(num3 + "，" +num2 +" ，"+num1); } }二、条件分支语句条件分支语句也叫 switch 语句（一） switch 语法switch(条件表达式){ case 表达式: 语句… break; case 表达式: 语句… break; default: 语句… break; }(1)switch…case 语句执行时，会依次将case后的表达式的值和switch后的表达式的值进行全等比较{alert type="success"}① 如果比较结果为true则从当前case处开始执行代码 ② 如果比较结果为false则从继续向下比较 ③ 如果所有的比较结果都为false，则执行default后的语句 {/alert}(2)使用 break; 可以退出switch语句(3)Switch语句和if语句有重复，可以互相代替var num = 1; switch(num){ case 1: console.log("壹") break; case 2: console.log("贰") break; default: console.log("数据不合法") break; }（二） 实例练习：对大于60分的输出“合格”，低于60分的输出“不合格”var score = 61; switch(parseInt(score/10)){ case 10: case 9: case 8: case 7: case 6: console.log("合格") break; default: console.log("不合格") break; }第二种方法var score = 61; switch(ttrue){ case sscore>=60: console.log("合格") break; default: console.log("不合格") break; }三、循环语句（一） while 循环 语法：while(条件表达式){ 语句…… }（1）while在语句执行时，先对条件表达式进行求值判断{alert type="success"}如果值为true，则执行循环体，循环体执行完毕后，继续对表达式进行判断如果为true则继续执行循环体如果值为false，则终止循环{/alert}（2）将条件表达式写死为true的循环叫做死循环，该循环不会停止，除非关闭浏览器（3）可以使用 break; 来终止循环while(true){ alert(n++); //判断n是否为10 if(n == 10){ //退出循环 break; } }（4）创建一个循环，往往需要三个步骤{alert type="error"}① 创建一个初始变量② 在循环中设置一个条件表达式③ 定义一个更新表达式，每次更新初始化变量{/alert}//① 创建一个初始变量 var n = 0; //② 在循环中设置一个条件表达式 while(n < 10){ //③ 定义一个更新表达式，每次更新初始化变量 document.write(n++ +' '); }（二） do…while 循环 语法：do{ 语句…… }while(条件表达式);（1）do…while 循环会先执行循环体，再对while后的表达式进行判断{alert type="success"}如果值为true，则执行循环体，循环体执行完毕后，继续对表达式进行判断如果为true则继续执行循环体如果值为false，则终止循环{/alert}（2）do…while 可以保证循环体至少执行一次var n = 11; do{ document.write(n++ +' '); }while(n <= 10);（3）死循环{callout color="#ff0000"} 尽量不要写死循环，会造成系统内存占用溢出，导致卡死 {/callout}（4）while 实战练习① 假如投资年利率为5%，试求从1000增长到5000需要多少年//定义一个变量，表示当前钱数 var money = 1000; //定义个一个计数器 var count = 0； while(money < 5000){ money *= 1.05; //使count自增 count++; } console.log("一共需要"+count+"年")②输入0-100的成绩后进行判断并输出相应的结果while(true){ var score = prompt("请输入成绩"); // 判断用户输入的值是否合法 if(score >=0 && score <= 100) { //满足该条件则证明用户的输入合法，退出循环 break; } alert("请输入有效的分数"); } if(score ==100) { alert("奖励BMW"); }else if(score >= 80){ alert("奖励手机"); }else if(score >= 60){ alert("奖励参考书"); }else{ alert("啥都没有"); }（三） for 循环 在for循环中，提供了专门的位置来放 初始化表达式 、 条件表达式 、 更新表达式 1、语法：for(①初始化表达式;②条件表达式;④更新表达式){ ③语句…… }（1）执行流程{alert type="error"}① 执行初始化表达式，初始化变量（只会执行一次）② 执行条件表达式，判断是否执行循环 如果为true则执行循环语句③，如果为false则终止循环 ④执行更新表达式，更新表达式执行完毕继续重复执行条件表达式②{/alert}（2）for循环中的三个表达式可以省略，也可以写在外部 如果在for循环中不写任何表达式，只写两个;;则变成死循环。 慎用！！！for(var i = 0 ; i < 10 ; i++ ){ alert(i); } for(;;){ alert("hello"); }2、实例练习（1）打印1-100之间所有奇数之和for(var i=1 , sum=0; i<=100 ; i++){ //判断i是否是奇数（不能被2整除的数就是奇数） //如果i除以2余数不为0则为奇数 if(i%2 != 0){ sum = sum+i; } }（2）打印1-100之间所有7的倍数的个数及总和for(var i=1 , sum=0 , count=0; i<=100 ; i++){ //如果i除以7余数为0则就是7的倍数 if(i%7 == 0){ sum += i; //使计数器自增 count++; } } console.log("总和为"+sum); // 输出总和 console.log("总数量为"+count); // 输出总和（3）打印所有水仙花数（一个3位数，它的每个位上的数字的3次幂之和等于它本身） 例如1^3+5^3+3^3=153//打印所有的三位数 for(var i=100; i<1000; i++){ //获取i的百位数字 var bai= parseInt(i/100); //获取十位数字 var shi= parseInt((i-bai*100)/10); //获取个位数字 var ge= i % 10; //判断i是否为水仙花数 if(bai*bai*bai + shi*shi*shi + ge*ge*ge == i){ console.log(i); } }（4）质数练习： 判断是否为质数（大于1的自然数，除了1和它本身不能被其他自然数整除的数叫做质数）var num =prompt("请输入一个大于1的整数"); //判断这个值是否合法 if(num <= 1){ alert("该值不合法"); }else{ // 判断num是否是质数 for(var i=2 ; i<num ; i++){ // 判断num是否能被i整除 if(num % i == 0){ // 如果num能被i整除则说明该值一定不是质数（反向证明） flag = false; } } // 创建一个变量来保存当前的数的状态，默认当前num为质数 var flag = true; //如果num是质数则输出 if(flag){ alert(num+ "是质数"); }else{ alert("这个数不是质数"); } }3、嵌套的的 for循环 （1）外部循环执行1次，内部循环就执行5次//向页面中输出内容 for(var i=0; i<5; i++){ for(var n=0; n<i+1; n++){ document.write("星 "); } //输出一个换行 document.write(" "); }（2）实例练习打印99乘法表<javascript> for(var i=1; i<=9; i++){ for(var n=1; n<=i; n++){ document.write(""+ n+ "*" + i+ "=" + i*n +""); } } </javascript> 四、 break 和 continue1、break关键字{alert type="success"}（1）break关键字可以用来退出switch或循环语句（2）不能在 if语句 中使用break和continue关键词（3）break关键字会立即终止离它最近的循环语句（不影响外层循环）for(var i=0; i<5; i++){ console.log("外层循环"+i); for(var j=0; j<5; j++){ break; console.log("内层循环"+j); } }{/alert}（4）可以为循环语句创建一个label，来标识当前的循环label:循环语句使用break语句时，可以在break后跟着一个label，这样break将会结束指定的循环，而不是最近的outer: for(var i=0; i<5; i++){ console.log("外层循环"+i); for(var j=0; j<5; j++){ break outer; console.log("内层循环"+j); } }2、continue关键词{alert type="success"}（1）continue关键词可以用来跳过当次循环（2）默认只会对离它最近的循环起作用（3） 与break用法类似 {/alert}outer: for(var i=0; i<5; i++){ for(var j=0; j<5; j++){ if(j == 1){ continue outer; } console.log("内层循环"+j); } console.log("外层循环"+i); }3、测试程序执行时间//开启计时器 console.time("test"); //停止计时器 console.timeEnd("test");4、 质数练习的改进 质数（大于1的自然数，除了1和它本身不能被其他自然数整除的数叫做质数）{alert type="success"}可以通过 Math.sqrt() 对一个数进行开方{/alert}//开启计时器 console.time("test"); for(var i=2; i<1000; i++){ var flag = true; for(var j=2; j<=Math.sqrt(i); j++){ if(i%j==0){ flag = false; //一旦进入判断，则证明i不可能位质数了，此时循环没有再执行的意义 //可以使用break来结束循环 break; } } if(flag){ console.log(i); } } //停止计时器 console.timeEnd("test");